VirtualBox

Changeset 53442 in vbox for trunk/src


Ignore:
Timestamp:
Dec 4, 2014 1:49:43 PM (10 years ago)
Author:
vboxsync
Message:

PDM Audio: Branch -> trunk.

Location:
trunk
Files:
10 added
1 deleted
21 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/VBox

  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r50708 r53442  
    55
    66/*
    7  * Copyright (C) 2006-2013 Oracle Corporation
     7 * Copyright (C) 2006-2014 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1919*   Header Files                                                               *
    2020*******************************************************************************/
     21#include <VBox/vmm/pdmdev.h>
     22#include <VBox/vmm/pdmaudioifs.h>
     23
     24#include <iprt/assert.h>
     25#include <iprt/mem.h>
     26#include <iprt/string.h>
     27#include <iprt/uuid.h>
     28
     29#include "VBoxDD.h"
     30
     31#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     32# include "AudioMixer.h"
     33#else
     34 extern "C" {
     35  #include "audio.h"
     36 }
     37#endif
     38
     39/*
     40#ifdef LOG_GROUP
     41 #undef LOG_GROUP
     42#endif
    2143#define LOG_GROUP LOG_GROUP_DEV_AUDIO
    22 #include <VBox/vmm/pdmdev.h>
    23 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    24 #include <VBox/vmm/pdmaudioifs.h>
    25 #endif
    26 #include <iprt/assert.h>
    27 #include <iprt/uuid.h>
    28 #include <iprt/string.h>
    29 
    30 #include "VBoxDD.h"
    31 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    32 extern "C" {
    33 #include "audio.h"
    34 }
    35 #endif
    36 
     44#include <VBox/log.h>
     45*/
    3746
    3847/*******************************************************************************
     
    4453#else
    4554# define USE_MIXER
     55#endif
     56
     57//#define DEBUG_LUN
     58#ifdef DEBUG_LUN
     59# define DEBUG_LUN_NUM 1
    4660#endif
    4761
     
    171185*   Structures and Typedefs                                                    *
    172186*******************************************************************************/
     187/**
     188 * Buffer descriptor.
     189 */
    173190typedef struct BD
    174191{
     
    187204    uint8_t  cr;                /**< rw 0, control register */
    188205    int      bd_valid;          /**< initialized? */
    189     BD       bd;
     206    BD       bd;                /**< buffer descriptor */
    190207} AC97BusMasterRegs;
    191208/** Pointer to a AC97 bus master register. */
    192209typedef AC97BusMasterRegs *PAC97BMREG;
    193210
     211#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     212/**
     213 * Struct for maintaining a host backend driver.
     214 */
     215typedef struct AC97STATE *PAC97STATE;
     216typedef struct AC97DRIVER
     217{
     218    /** Pointer to AC97 controller (state). */
     219    PAC97STATE                         pAC97State;
     220    /** LUN # to which this driver has been assigned. */
     221    uint8_t                            uLUN;
     222    /** Audio connector interface to the underlying
     223     *  host backend. */
     224    R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pConnector;
     225    /** PCM input stream. */
     226    R3PTRTYPE(PPDMAUDIOGSTSTRMIN)      pStrmIn;
     227    /** Mixer handle for input stream. */
     228    R3PTRTYPE(PAUDMIXSTREAM)           phStrmIn;
     229    /** PCM output stream. */
     230    R3PTRTYPE(PPDMAUDIOGSTSTRMOUT)     pStrmOut;
     231    /** PCM microphone input stream. */
     232    R3PTRTYPE(PPDMAUDIOGSTSTRMIN)      pStrmMic;
     233    /** Mixer handle for output stream. */
     234    R3PTRTYPE(PAUDMIXSTREAM)           phStrmMic;
     235} AC97DRIVER;
     236/** Pointer to a AC97 driver. */
     237typedef AC97DRIVER *PAC97DRIVER;
     238#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     239
    194240typedef struct AC97STATE
    195241{
     
    197243    PCIDevice               PciDev;
    198244
    199     /** Audio stuff.  */
    200 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    201     QEMUSoundCard card;
    202 #endif
     245    /** Audio stuff. */
    203246    /** Global Control (Bus Master Control Register) */
    204247    uint32_t                glob_cnt;
     
    212255    uint8_t                 mixer_data[256];
    213256#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    214     /** PCM in */
    215     PPDMGSTVOICEIN          voice_pi[2];
    216     /** PCM out */
    217     PPDMGSTVOICEOUT         voice_po[2];
    218     /** Mic in */
    219     PPDMGSTVOICEIN          voice_mc[2];
    220 #else
     257    /** Number of active + allocated LUNs. Each
     258     *  LUN has an AC'97 driver assigned. */
     259    uint8_t                 cLUNs;
     260    /** Array of active AC'97 drivers. */
     261    R3PTRTYPE(PAC97DRIVER)  paDrv[32];
     262    /** The device' software mixer. */
     263    R3PTRTYPE(PAUDIOMIXER)  pMixer;
     264    /** Audio sink for line input. */
     265    R3PTRTYPE(PAUDMIXSINK)  pSinkLineIn;
     266    /** Audio sink for microphone input. */
     267    R3PTRTYPE(PAUDMIXSINK)  pSinkMicIn;
     268#else
     269    QEMUSoundCard           card;
    221270    /** PCM in */
    222271    SWVoiceIn              *voice_pi;
     
    225274    /** Mic in */
    226275    SWVoiceIn              *voice_mc;
    227 #endif
     276#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    228277    uint8_t                 silence[128];
    229278    int                     bup_flag;
    230279    /** Pointer to the device instance. */
    231280    PPDMDEVINSR3            pDevIns;
    232     /** Pointer to the connector of the attached audio driver. */
    233 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    234     PPDMIAUDIOCONNECTOR     pDrv[2];
    235 #else
    236     PPDMIAUDIOCONNECTOR     pDrv;
    237 #endif
    238281    /** Pointer to the attached audio driver. */
    239282    PPDMIBASE               pDrvBase;
     
    286329#define GET_BM(a_idx)   ( ((a_idx) >> 4) & 3 )
    287330
    288 static void po_callback(void *opaque, int free);
    289 static void pi_callback(void *opaque, int avail);
    290 static void mc_callback(void *opaque, int avail);
    291 
    292 static void warm_reset(PAC97STATE pThis)
     331#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     332static void ichac97OutputCallback(void *pvContext, uint32_t cbFree);
     333static void ichac97InputCallback(void *pvContext, uint32_t cbAvail);
     334static void ichac97MicInCallback(void *pvContext, uint32_t cbAvail);
     335#else
     336static void ichac97OutputCallback(void *pvContext, int cbFree);
     337static void ichac97InputCallback(void *pvContext, int cbAvail);
     338static void ichac97MicInCallback(void *pvContext, int cbAvail);
     339#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     340
     341static void ichac97WarmReset(PAC97STATE pThis)
    293342{
    294343    NOREF(pThis);
    295344}
    296345
    297 static void cold_reset(PAC97STATE pThis)
     346static void ichac97ColdReset(PAC97STATE pThis)
    298347{
    299348    NOREF(pThis);
    300349}
    301350
    302 /** Fetch Buffer Descriptor at _CIV */
    303 static void fetch_bd(PAC97STATE pThis, PAC97BMREG pReg)
     351/** Fetches the buffer descriptor at _CIV. */
     352static void ichac97FetchBufDesc(PAC97STATE pThis, PAC97BMREG pReg)
    304353{
    305354    PPDMDEVINS pDevIns = ICHAC97STATE_2_DEVINS(pThis);
     
    315364#endif
    316365    pReg->picb       = pReg->bd.ctl_len & 0xffff;
    317     Log(("ac97: bd %2d addr=%#x ctl=%#06x len=%#x(%d bytes)\n",
    318          pReg->civ, pReg->bd.addr, pReg->bd.ctl_len >> 16,
    319          pReg->bd.ctl_len & 0xffff, (pReg->bd.ctl_len & 0xffff) << 1));
     366    LogFlowFunc(("bd %2d addr=%#x ctl=%#06x len=%#x(%d bytes)\n",
     367                  pReg->civ, pReg->bd.addr, pReg->bd.ctl_len >> 16,
     368                  pReg->bd.ctl_len & 0xffff, (pReg->bd.ctl_len & 0xffff) << 1));
    320369}
    321370
     
    323372 * Update the BM status register
    324373 */
    325 static void update_sr(PAC97STATE pThis, PAC97BMREG pReg, uint32_t new_sr)
     374static void ichac97UpdateStatus(PAC97STATE pThis, PAC97BMREG pReg, uint32_t new_sr)
    326375{
    327376    PPDMDEVINS  pDevIns = ICHAC97STATE_2_DEVINS(pThis);
     
    354403    pReg->sr = new_sr;
    355404
    356     Log(("ac97: IOC%d LVB%d sr=%#x event=%d level=%d\n",
    357          pReg->sr & SR_BCIS, pReg->sr & SR_LVBCI, pReg->sr, event, level));
     405    LogFlowFunc(("IOC%d LVB%d sr=%#x event=%d level=%d\n",
     406                 pReg->sr & SR_BCIS, pReg->sr & SR_LVBCI, pReg->sr, event, level));
    358407
    359408    if (event)
     
    364413            pThis->glob_sta &= ~masks[pReg - pThis->bm_regs];
    365414
    366         Log(("ac97: set irq level=%d\n", !!level));
     415        LogFlowFunc(("set irq level=%d\n", !!level));
    367416        PDMDevHlpPCISetIrq(pDevIns, 0, !!level);
    368417    }
    369418}
    370419
    371 static void voice_set_active(PAC97STATE pThis, int bm_index, int on)
    372 {
     420static void ichac97StreamSetActive(PAC97STATE pThis, int bm_index, int on)
     421{
     422    AssertPtrReturnVoid(pThis);
     423
     424    LogFlowFunc(("index=%d, on=%d\n", bm_index, on));
     425
     426#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    373427    switch (bm_index)
    374428    {
    375 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    376         uint32_t lun;
    377429        case PI_INDEX:
    378             for (lun = 0; lun < 2; lun++)
    379                 pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_pi[lun], on);
     430            for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     431                pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector,
     432                                                           pThis->paDrv[lun]->pStrmIn, RT_BOOL(on));
    380433            break;
     434
    381435        case PO_INDEX:
    382             for (lun = 0; lun < 2; lun++)
    383                 pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->voice_po[lun], on);
    384         break;
     436            for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     437                pThis->paDrv[lun]->pConnector->pfnEnableOut(pThis->paDrv[lun]->pConnector,
     438                                                            pThis->paDrv[lun]->pStrmOut, RT_BOOL(on));
     439            break;
     440
    385441        case MC_INDEX:
    386             for (lun = 0; lun < 2; lun++)
    387                 pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_mc[lun], on);
     442            for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     443                pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector,
     444                                                           pThis->paDrv[lun]->pStrmMic, RT_BOOL(on));
    388445            break;
    389 #else
     446
     447        default:
     448            AssertMsgFailed(("Wrong index %d\n", bm_index));
     449            break;
     450    }
     451#else
     452    switch (bm_index)
     453    {
    390454        case PI_INDEX: AUD_set_active_in( pThis->voice_pi, on); break;
    391455        case PO_INDEX: AUD_set_active_out(pThis->voice_po, on); break;
    392456        case MC_INDEX: AUD_set_active_in( pThis->voice_mc, on); break;
    393 #endif
    394457        default:       AssertFailed (); break;
    395458    }
    396 }
    397 
    398 static void reset_bm_regs(PAC97STATE pThis, PAC97BMREG pReg)
    399 {
    400     Log(("ac97: reset_bm_regs\n"));
     459#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     460}
     461
     462static void ichac97ResetBMRegs(PAC97STATE pThis, PAC97BMREG pReg)
     463{
     464    LogFlowFunc(("reset_bm_regs\n"));
    401465    pReg->bdbar    = 0;
    402466    pReg->civ      = 0;
    403467    pReg->lvi      = 0;
    404468    /** @todo do we need to do that? */
    405     update_sr(pThis, pReg, SR_DCH);
     469    ichac97UpdateStatus(pThis, pReg, SR_DCH);
    406470    pReg->picb     = 0;
    407471    pReg->piv      = 0;
    408472    pReg->cr       = pReg->cr & CR_DONT_CLEAR_MASK;
    409473    pReg->bd_valid = 0;
    410     voice_set_active(pThis, pReg - pThis->bm_regs, 0);
    411     memset(pThis->silence, 0, sizeof(pThis->silence));
    412 }
    413 
    414 static void mixer_store(PAC97STATE pThis, uint32_t i, uint16_t v)
     474    ichac97StreamSetActive(pThis, pReg - pThis->bm_regs, 0);
     475    RT_ZERO(pThis->silence);
     476}
     477
     478static void ichac97MixerStore(PAC97STATE pThis, uint32_t i, uint16_t v)
    415479{
    416480    if (i + 2 > sizeof(pThis->mixer_data))
    417481    {
    418         Log(("ac97: mixer_store: index %d out of bounds %d\n", i, sizeof(pThis->mixer_data)));
     482        LogFlowFunc(("mixer_store: index %d out of bounds %d\n", i, sizeof(pThis->mixer_data)));
    419483        return;
    420484    }
     
    424488}
    425489
    426 static uint16_t mixer_load(PAC97STATE pThis, uint32_t i)
     490static uint16_t ichac97MixerLoad(PAC97STATE pThis, uint32_t i)
    427491{
    428492    uint16_t val;
     
    430494    if (i + 2 > sizeof(pThis->mixer_data))
    431495    {
    432         Log(("ac97: mixer_store: index %d out of bounds %d\n", i, sizeof(pThis->mixer_data)));
     496        LogFlowFunc(("mixer_store: index %d out of bounds %d\n", i, sizeof(pThis->mixer_data)));
    433497        val = 0xffff;
    434498    }
     
    439503}
    440504
    441 static void open_voice(PAC97STATE pThis, int index, int freq)
    442 {
    443 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     505static void ichac97OpenStream(PAC97STATE pThis, int index, uint16_t freq)
     506{
     507    LogFlowFunc(("index=%d, freq=%RU16\n", index, freq));
     508
    444509    int rc;
    445 #endif
    446     LogFlow(("DevIchAC97: open_voice freq = %d\n", freq));
     510
     511#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    447512    if (freq)
    448513    {
    449 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER
     514        PDMAUDIOSTREAMCFG streamCfg;
     515        RT_ZERO(streamCfg);
     516        streamCfg.uHz           = freq;
     517        streamCfg.cChannels     = 2;
     518        streamCfg.enmFormat     = AUD_FMT_S16;
     519        streamCfg.enmEndianness = PDMAUDIOHOSTENDIANESS;
     520
     521        char *pszDesc;
     522
     523        switch (index)
     524        {
     525            case PI_INDEX: /* PCM in */
     526                for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     527                {
     528                    if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] ac97.pi", lun) <= 0)
     529                    {
     530                        rc = VERR_NO_MEMORY;
     531                        break;
     532                    }
     533
     534                    rc = pThis->paDrv[lun]->pConnector->pfnOpenIn(pThis->paDrv[lun]->pConnector,
     535                                                                  pszDesc, PDMAUDIORECSOURCE_LINE_IN,
     536                                                                  ichac97InputCallback, pThis->paDrv[lun] /* pvContext */,
     537                                                                  &streamCfg,
     538                                                                  &pThis->paDrv[lun]->pStrmIn);
     539                    LogFlowFunc(("LUN#%RU8: Opened line input with rc=%Rrc\n", lun, rc));
     540                    if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */
     541                    {
     542                        audioMixerRemoveStream(pThis->pSinkLineIn, pThis->paDrv[lun]->phStrmIn);
     543                        rc = audioMixerAddStreamIn(pThis->pSinkLineIn,
     544                                                   pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn,
     545                                                   0 /* uFlags */,
     546                                                   &pThis->paDrv[lun]->phStrmIn);
     547                    }
     548
     549                    RTStrFree(pszDesc);
     550                }
     551                break;
     552
     553            case PO_INDEX: /* PCM out */
     554                for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     555                {
     556                    if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] ac97.po", lun) <= 0)
     557                    {
     558                        rc = VERR_NO_MEMORY;
     559                        break;
     560                    }
     561
     562                    rc = pThis->paDrv[lun]->pConnector->pfnOpenOut(pThis->paDrv[lun]->pConnector, pszDesc,
     563                                                                   ichac97OutputCallback, pThis->paDrv[lun] /* pvContext */,
     564                                                                   &streamCfg,
     565                                                                   &pThis->paDrv[lun]->pStrmOut);
     566                    LogFlowFunc(("LUN#%RU8: Opened output with rc=%Rrc\n", lun, rc));
     567                    RTStrFree(pszDesc);
     568                }
     569                break;
     570
     571            case MC_INDEX: /* Mic in */
     572                for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     573                {
     574                    if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] ac97.mc", lun) <= 0)
     575                    {
     576                        rc = VERR_NO_MEMORY;
     577                        break;
     578                    }
     579
     580                    rc = pThis->paDrv[lun]->pConnector->pfnOpenIn(pThis->paDrv[lun]->pConnector,
     581                                                                  pszDesc, PDMAUDIORECSOURCE_MIC,
     582                                                                  ichac97MicInCallback, pThis->paDrv[lun] /* pvContext */,
     583                                                                  &streamCfg,
     584                                                                  &pThis->paDrv[lun]->pStrmMic);
     585                    LogFlowFunc(("LUN#%RU8: Opened mic input with rc=%Rrc\n", lun, rc));
     586                    if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */
     587                    {
     588                        audioMixerRemoveStream(pThis->pSinkMicIn, pThis->paDrv[lun]->phStrmMic);
     589                        rc = audioMixerAddStreamIn(pThis->pSinkMicIn,
     590                                                   pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic,
     591                                                   0 /* uFlags */,
     592                                                   &pThis->paDrv[lun]->phStrmMic);
     593                    }
     594
     595                    RTStrFree(pszDesc);
     596                }
     597                break;
     598
     599            default:
     600                AssertMsgFailed(("Unsupported index %d\n", index));
     601                break;
     602        }
     603    }
     604    else
     605    {
     606        switch (index)
     607        {
     608            case PI_INDEX:
     609                for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     610                {
     611                    pThis->paDrv[lun]->pConnector->pfnCloseIn(pThis->paDrv[lun]->pConnector,
     612                                                              pThis->paDrv[lun]->pStrmIn);
     613                    audioMixerRemoveStream(pThis->pSinkLineIn,
     614                                           pThis->paDrv[lun]->phStrmIn);
     615                    pThis->paDrv[lun]->pStrmIn = NULL;
     616                    pThis->paDrv[lun]->phStrmIn = NULL;
     617                }
     618
     619                LogFlowFunc(("Closed line input\n"));
     620                break;
     621
     622            case PO_INDEX:
     623                for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     624                {
     625                    pThis->paDrv[lun]->pConnector->pfnCloseOut(pThis->paDrv[lun]->pConnector,
     626                                                               pThis->paDrv[lun]->pStrmOut);
     627                    pThis->paDrv[lun]->pStrmOut = NULL;
     628                }
     629
     630                LogFlowFunc(("Closed output\n"));
     631                break;
     632
     633            case MC_INDEX:
     634                for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     635                {
     636                    pThis->paDrv[lun]->pConnector->pfnCloseIn(pThis->paDrv[lun]->pConnector,
     637                                                              pThis->paDrv[lun]->pStrmMic);
     638                    audioMixerRemoveStream(pThis->pSinkMicIn,
     639                                           pThis->paDrv[lun]->phStrmMic);
     640                    pThis->paDrv[lun]->pStrmMic = NULL;
     641                    pThis->paDrv[lun]->phStrmMic = NULL;
     642                }
     643
     644                LogFlowFunc(("Closed mic input\n"));
     645                break;
     646
     647            default:
     648                AssertMsgFailed(("Unsupported index %d\n", index));
     649                break;
     650        }
     651
     652        rc = VINF_SUCCESS;
     653    }
     654#else
     655    if (freq)
     656    {
    450657        audsettings_t as;
    451658        as.freq       = freq;
     
    453660        as.fmt        = AUD_FMT_S16;
    454661        as.endianness = 0;
    455         uint32_t lun;
    456 #endif
     662
    457663        switch (index)
    458664        {
    459665            case PI_INDEX: /* PCM in */
    460 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    461                 for (uint32_t lun = 0; lun < 2; lun++)
    462                     rc = pThis->pDrv[lun]->pfnOpenIn(pThis->pDrv[lun], &pThis->voice_pi[lun], "ac97.pi",
    463                                                      pThis, pi_callback, freq, 2, AUD_FMT_S16, 0);
    464 #else
    465                 pThis->voice_pi = AUD_open_in(&pThis->card, pThis->voice_pi, "ac97.pi", pThis, pi_callback, &as);
    466 #endif
     666                pThis->voice_pi = AUD_open_in(&pThis->card, pThis->voice_pi, "ac97.pi", pThis, ichac97InputCallback, &as);
    467667#ifdef LOG_VOICES
    468668                LogRel(("AC97: open PI freq=%d (%s)\n", freq, pThis->voice_pi ? "ok" : "FAIL"));
    469669#endif
     670                rc = pThis->voice_pi ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
    470671                break;
    471672
    472673            case PO_INDEX: /* PCM out */
    473 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    474                 for (int lun = 0; lun < 2; lun++)
    475                 {
    476                     LogFlow(("LUN###%d\n", lun));
    477                     rc = pThis->pDrv[lun]->pfnOpenOut(pThis->pDrv[lun], &pThis->voice_po[lun], "ac97.po",
    478                                                       pThis, po_callback, freq, 2, AUD_FMT_S16, 0);
    479                 }
    480 #else
    481                 pThis->voice_po = AUD_open_out(&pThis->card, pThis->voice_po, "ac97.po", pThis, po_callback, &as);
    482 #endif
     674                pThis->voice_po = AUD_open_out(&pThis->card, pThis->voice_po, "ac97.po", pThis, ichac97OutputCallback, &as);
    483675#ifdef LOG_VOICES
    484676                LogRel(("AC97: open PO freq=%d (%s)\n", freq, pThis->voice_po ? "ok" : "FAIL"));
    485677#endif
     678                rc = pThis->voice_po ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
    486679                break;
    487680
    488681            case MC_INDEX: /* Mic in */
    489 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    490                 for (uint32_t lun = 0; lun < 2; lun++)
    491                     rc = pThis->pDrv[lun]->pfnOpenIn(pThis->pDrv[lun], &pThis->voice_mc[lun], "ac97.mc",
    492                                                      pThis, mc_callback, freq, 2, AUD_FMT_S16, 0);
    493 #else
    494                 pThis->voice_mc = AUD_open_in(&pThis->card, pThis->voice_mc, "ac97.mc", pThis, mc_callback, &as);
    495 #endif
     682                pThis->voice_mc = AUD_open_in(&pThis->card, pThis->voice_mc, "ac97.mc", pThis, ichac97MicInCallback, &as);
    496683#ifdef LOG_VOICES
    497684                LogRel(("AC97: open MC freq=%d (%s)\n", freq, pThis->voice_mc ? "ok" : "FAIL"));
    498685#endif
     686                rc = pThis->voice_mc ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
    499687                break;
    500688        }
     
    505693        {
    506694            case PI_INDEX:
    507 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    508                 for (uint32_t lun = 0; lun < 2; lun++)
    509                 {
    510                     pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_pi[lun]);
    511                     pThis->voice_pi[lun] = NULL;
    512                 }
    513 #else
    514695                AUD_close_in(&pThis->card, pThis->voice_pi);
    515696                pThis->voice_pi = NULL;
    516 #endif
    517697#ifdef LOG_VOICES
    518698                LogRel(("AC97: Closing PCM IN\n"));
     
    521701
    522702            case PO_INDEX:
    523 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    524                 for (uint32_t lun = 0; lun < 2; lun++)
    525                 {
    526                     pThis->pDrv[lun]->pfnCloseOut(pThis->pDrv[lun], pThis->voice_po[lun]);
    527                     pThis->voice_po[lun] = NULL;
    528                 }
    529 #else
    530703                AUD_close_out(&pThis->card, pThis->voice_po);
    531704                pThis->voice_po = NULL;
    532 #endif
    533705#ifdef LOG_VOICES
    534706                LogRel(("AC97: Closing PCM OUT\n"));
     
    537709
    538710            case MC_INDEX:
    539 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    540                 for (uint32_t lun = 0; lun < 2; lun++)
    541                 {
    542                     pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_mc[lun]);
    543                     pThis->voice_mc[lun] = NULL;
    544                 }
    545 #else
    546711                AUD_close_in(&pThis->card, pThis->voice_mc);
    547712                pThis->voice_mc = NULL;
    548 #endif
    549713#ifdef LOG_VOICES
    550714                LogRel(("AC97: Closing MIC IN\n"));
     
    552716                break;
    553717        }
    554     }
    555 }
    556 
    557 static void reset_voices(PAC97STATE pThis, uint8_t active[LAST_INDEX])
    558 {
    559     uint16_t freq;
    560 
    561     freq = mixer_load(pThis, AC97_PCM_LR_ADC_Rate);
    562     open_voice(pThis, PI_INDEX, freq);
    563 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    564     for (uint32_t lun = 0; lun < 2; lun++)
    565         pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_pi[lun], active[PI_INDEX]);
     718
     719        rc = VINF_SUCCESS;
     720    }
     721#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     722
     723    LogFlowFuncLeaveRC(rc);
     724}
     725
     726/** @todo r=andy D'oh, pretty bad argument handling -- fix this! */
     727static void ichac97ResetStreams(PAC97STATE pThis, uint8_t active[LAST_INDEX])
     728{
     729    uint16_t uFreq = ichac97MixerLoad(pThis, AC97_PCM_LR_ADC_Rate);
     730    bool fEnable = RT_BOOL(active[PI_INDEX]);
     731    LogFlowFunc(("Input ADC uFreq=%RU16, fEnabled=%RTbool\n", uFreq, fEnable));
     732
     733    ichac97OpenStream(pThis, PI_INDEX, uFreq);
     734
     735#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     736    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     737        pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector,
     738                                                   pThis->paDrv[lun]->pStrmIn, fEnable);
    566739#else
    567740    AUD_set_active_in(pThis->voice_pi, active[PI_INDEX]);
    568 #endif
    569     freq = mixer_load(pThis, AC97_PCM_Front_DAC_Rate);
    570     LogFlow(("DevIchAC97: reset_voices calling open_voice freq = %d\n", freq));
    571     open_voice(pThis, PO_INDEX, freq);
    572 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    573     for (uint32_t lun = 0; lun < 2; lun++)
    574         pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->voice_po[lun], active[PO_INDEX]);
     741#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     742
     743    uFreq = ichac97MixerLoad(pThis, AC97_PCM_Front_DAC_Rate);
     744    fEnable = RT_BOOL(active[PO_INDEX]);
     745    LogFlowFunc(("Output DAC uFreq=%RU16, fEnabled=%RTbool\n", uFreq, fEnable));
     746
     747    ichac97OpenStream(pThis, PO_INDEX, uFreq);
     748
     749#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     750    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     751        pThis->paDrv[lun]->pConnector->pfnEnableOut(pThis->paDrv[lun]->pConnector,
     752                                                    pThis->paDrv[lun]->pStrmOut, fEnable);
    575753#else
    576754    AUD_set_active_out(pThis->voice_po, active[PO_INDEX]);
    577 #endif
    578 
    579     freq = mixer_load(pThis, AC97_MIC_ADC_Rate);
    580     open_voice(pThis, MC_INDEX, freq);
    581 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    582     for (uint32_t lun = 0; lun < 2; lun++)
    583         pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_mc[lun], active[MC_INDEX]);
    584 #else
    585     AUD_set_active_in(pThis->voice_mc, active[MC_INDEX]);
    586 #endif
     755#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     756
     757    uFreq = ichac97MixerLoad(pThis, AC97_MIC_ADC_Rate);
     758    fEnable = RT_BOOL(active[MC_INDEX]);
     759    LogFlowFunc(("Mic ADC uFreq=%RU16, fEnabled=%RTbool\n", uFreq, fEnable));
     760
     761    ichac97OpenStream(pThis, MC_INDEX, uFreq);
     762
     763#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     764    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     765        pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector,
     766                                                   pThis->paDrv[lun]->pStrmMic, fEnable);
     767#else
     768     AUD_set_active_in(pThis->voice_mc, active[MC_INDEX]);
     769#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    587770}
    588771
    589772#ifdef USE_MIXER
    590773
    591 static void set_volume(PAC97STATE pThis, int index, audmixerctl_t mt, uint32_t val)
     774#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     775static void ichac97SetVolume(PAC97STATE pThis, int index, PDMAUDIOMIXERCTL mt, uint32_t val)
     776#else
     777static void ichac97SetVolume(PAC97STATE pThis, int index, audmixerctl_t mt, uint32_t val)
     778#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    592779{
    593780    int mute = (val >> MUTE_SHIFT) & 1;
     
    597784    lvol = 255 * lvol / VOL_MASK;
    598785
    599 # ifdef SOFT_VOLUME
     786#ifdef SOFT_VOLUME
    600787    if (index == AC97_Master_Volume_Mute)
    601788    {
    602 #  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    603     for (uint32_t lun = 0; lun < 1; lun++)
    604         pThis->pDrv[lun]->pfnIsSetOutVolume(pThis->pDrv[lun], pThis->voice_po[lun], mute, lvol, rvol);
    605 #  else
     789# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     790        for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     791        {
     792            pThis->paDrv[lun]->pConnector->pfnIsSetOutVolume(pThis->paDrv[lun]->pConnector,
     793                                                             pThis->paDrv[lun]->pStrmOut,
     794                                                             RT_BOOL(mute), lvol, rvol);
     795        }
     796# else
    606797        AUD_set_volume_out(pThis->voice_po, mute, lvol, rvol);
    607 #  endif
     798# endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    608799    }
    609800    else
    610801    {
    611 #  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    612         for (uint32_t lun = 0; lun < 1; lun++)
    613             /* @tod0 in SetVolume no passing audmixerctl_in as its not used in DrvAudio.c */
    614             pThis->pDrv[lun]->pfnSetVolume(pThis->pDrv[lun], &mute, &lvol, &rvol);
    615 #  else
     802# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     803        for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     804        {
     805            /** @todo In SetVolume no passing audmixerctl_in as its not used in DrvAudio.c */
     806            pThis->paDrv[lun]->pConnector->pfnSetVolume(pThis->paDrv[lun]->pConnector,
     807                                                        RT_BOOL(mute), lvol, rvol);
     808        }
     809# else
    616810        AUD_set_volume(mt, &mute, &lvol, &rvol);
    617 #  endif
    618     }
     811# endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     812    }
     813#else /* !SOFT_VOLUME */
     814# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     815    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     816        pThis->paDrv[lun]->pConnector->pfnSetVolume(pThis->paDrv[lun]->pConnector,
     817                                                    RT_BOOL(mute), lvol, rvol);
    619818# else
    620 #  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    621     for (uint32_t lun = 0; lun < 1; lun++)
    622         pThis->pDrv[lun]->pfnSetVolume(pThis->pDrv[lun], &mute, &lvol, &rvol);
    623 #  else
    624819    AUD_set_volume(mt, &mute, &lvol, &rvol);
    625 #  endif
    626 # endif
     820# endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     821#endif /* SOFT_VOLUME */
    627822
    628823    rvol = VOL_MASK - ((VOL_MASK * rvol) / 255);
     
    642837        val |= RT_BIT(12) | RT_BIT(11) | RT_BIT(10) | RT_BIT(9) | RT_BIT(8);
    643838
    644     mixer_store(pThis, index, val);
    645 }
    646 
    647 static audrecsource_t ac97_to_aud_record_source(uint8_t i)
     839    ichac97MixerStore(pThis, index, val);
     840}
     841
     842static PDMAUDIORECSOURCE ichac97IndextoRecSource(uint8_t i)
    648843{
    649844    switch (i)
    650845    {
    651         case REC_MIC:     return AUD_REC_MIC;
    652         case REC_CD:      return AUD_REC_CD;
    653         case REC_VIDEO:   return AUD_REC_VIDEO;
    654         case REC_AUX:     return AUD_REC_AUX;
    655         case REC_LINE_IN: return AUD_REC_LINE_IN;
    656         case REC_PHONE:   return AUD_REC_PHONE;
     846        case REC_MIC:     return PDMAUDIORECSOURCE_MIC;
     847        case REC_CD:      return PDMAUDIORECSOURCE_CD;
     848        case REC_VIDEO:   return PDMAUDIORECSOURCE_VIDEO;
     849        case REC_AUX:     return PDMAUDIORECSOURCE_AUX;
     850        case REC_LINE_IN: return PDMAUDIORECSOURCE_LINE_IN;
     851        case REC_PHONE:   return PDMAUDIORECSOURCE_PHONE;
    657852        default:
    658             Log(("ac97: Unknown record source %d, using MIC\n", i));
    659             return AUD_REC_MIC;
    660     }
    661 }
    662 
    663 static uint8_t aud_to_ac97_record_source(audrecsource_t rs)
     853            break;
     854    }
     855
     856    LogFlowFunc(("Unknown record source %d, using MIC\n", i));
     857    return PDMAUDIORECSOURCE_MIC;
     858}
     859
     860static uint8_t ichac97RecSourceToIndex(PDMAUDIORECSOURCE rs)
    664861{
    665862    switch (rs)
    666863    {
    667         case AUD_REC_MIC:     return REC_MIC;
    668         case AUD_REC_CD:      return REC_CD;
    669         case AUD_REC_VIDEO:   return REC_VIDEO;
    670         case AUD_REC_AUX:     return REC_AUX;
    671         case AUD_REC_LINE_IN: return REC_LINE_IN;
    672         case AUD_REC_PHONE:   return REC_PHONE;
     864        case PDMAUDIORECSOURCE_MIC:     return REC_MIC;
     865        case PDMAUDIORECSOURCE_CD:      return REC_CD;
     866        case PDMAUDIORECSOURCE_VIDEO:   return REC_VIDEO;
     867        case PDMAUDIORECSOURCE_AUX:     return REC_AUX;
     868        case PDMAUDIORECSOURCE_LINE_IN: return REC_LINE_IN;
     869        case PDMAUDIORECSOURCE_PHONE:   return REC_PHONE;
    673870        default:
    674             Log(("ac97: Unknown audio recording source %d using MIC\n", rs));
    675             return REC_MIC;
    676     }
    677 }
    678 
    679 static void record_select(PAC97STATE pThis, uint32_t val)
     871            break;
     872    }
     873
     874    LogFlowFunc(("Unknown audio recording source %d using MIC\n", rs));
     875    return REC_MIC;
     876}
     877
     878static void ichac97RecordSelect(PAC97STATE pThis, uint32_t val)
    680879{
    681880    uint8_t rs = val & REC_MASK;
    682881    uint8_t ls = (val >> 8) & REC_MASK;
    683     audrecsource_t ars = ac97_to_aud_record_source(rs);
    684     audrecsource_t als = ac97_to_aud_record_source(ls);
     882    PDMAUDIORECSOURCE ars = ichac97IndextoRecSource(rs);
     883    PDMAUDIORECSOURCE als = ichac97IndextoRecSource(ls);
    685884    //AUD_set_record_source(&als, &ars);
    686     rs = aud_to_ac97_record_source(ars);
    687     ls = aud_to_ac97_record_source(als);
    688     mixer_store(pThis, AC97_Record_Select, rs | (ls << 8));
     885    rs = ichac97RecSourceToIndex(ars);
     886    ls = ichac97RecSourceToIndex(als);
     887    ichac97MixerStore(pThis, AC97_Record_Select, rs | (ls << 8));
    689888}
    690889
    691890#endif /* USE_MIXER */
    692891
    693 static void mixer_reset(PAC97STATE pThis)
    694 {
    695     uint8_t active[LAST_INDEX];
    696 
    697     Log(("ac97: mixer_reset\n"));
    698     memset(pThis->mixer_data, 0, sizeof(pThis->mixer_data));
    699     memset(active, 0, sizeof(active));
    700     mixer_store(pThis, AC97_Reset                   , 0x0000); /* 6940 */
    701     mixer_store(pThis, AC97_Master_Volume_Mono_Mute , 0x8000);
    702     mixer_store(pThis, AC97_PC_BEEP_Volume_Mute     , 0x0000);
    703 
    704     mixer_store(pThis, AC97_Phone_Volume_Mute       , 0x8008);
    705     mixer_store(pThis, AC97_Mic_Volume_Mute         , 0x8008);
    706     mixer_store(pThis, AC97_CD_Volume_Mute          , 0x8808);
    707     mixer_store(pThis, AC97_Aux_Volume_Mute         , 0x8808);
    708     mixer_store(pThis, AC97_Record_Gain_Mic_Mute    , 0x8000);
    709     mixer_store(pThis, AC97_General_Purpose         , 0x0000);
    710     mixer_store(pThis, AC97_3D_Control              , 0x0000);
    711     mixer_store(pThis, AC97_Powerdown_Ctrl_Stat     , 0x000f);
     892static void ichac97MixerReset(PAC97STATE pThis)
     893{
     894    LogFlowFuncEnter();
     895
     896    RT_ZERO(pThis->mixer_data);
     897
     898#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     899    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     900    {
     901        pThis->paDrv[lun]->phStrmIn = NULL;
     902        pThis->paDrv[lun]->phStrmMic = NULL;
     903    }
     904
     905    pThis->pSinkLineIn = NULL;
     906    pThis->pSinkMicIn = NULL;
     907
     908    if (pThis->pMixer)
     909    {
     910        audioMixerDestroy(pThis->pMixer);
     911        pThis->pMixer = NULL;
     912    }
     913#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     914
     915    ichac97MixerStore(pThis, AC97_Reset                   , 0x0000); /* 6940 */
     916    ichac97MixerStore(pThis, AC97_Master_Volume_Mono_Mute , 0x8000);
     917    ichac97MixerStore(pThis, AC97_PC_BEEP_Volume_Mute     , 0x0000);
     918
     919    ichac97MixerStore(pThis, AC97_Phone_Volume_Mute       , 0x8008);
     920    ichac97MixerStore(pThis, AC97_Mic_Volume_Mute         , 0x8008);
     921    ichac97MixerStore(pThis, AC97_CD_Volume_Mute          , 0x8808);
     922    ichac97MixerStore(pThis, AC97_Aux_Volume_Mute         , 0x8808);
     923    ichac97MixerStore(pThis, AC97_Record_Gain_Mic_Mute    , 0x8000);
     924    ichac97MixerStore(pThis, AC97_General_Purpose         , 0x0000);
     925    ichac97MixerStore(pThis, AC97_3D_Control              , 0x0000);
     926    ichac97MixerStore(pThis, AC97_Powerdown_Ctrl_Stat     , 0x000f);
    712927
    713928    /*
    714929     * Sigmatel 9700 (STAC9700)
    715930     */
    716     mixer_store(pThis, AC97_Vendor_ID1              , 0x8384);
    717     mixer_store(pThis, AC97_Vendor_ID2              , 0x7600); /* 7608 */
    718 
    719     mixer_store(pThis, AC97_Extended_Audio_ID       , 0x0809);
    720     mixer_store(pThis, AC97_Extended_Audio_Ctrl_Stat, 0x0009);
    721     mixer_store(pThis, AC97_PCM_Front_DAC_Rate      , 0xbb80);
    722     mixer_store(pThis, AC97_PCM_Surround_DAC_Rate   , 0xbb80);
    723     mixer_store(pThis, AC97_PCM_LFE_DAC_Rate        , 0xbb80);
    724     mixer_store(pThis, AC97_PCM_LR_ADC_Rate         , 0xbb80);
    725     mixer_store(pThis, AC97_MIC_ADC_Rate            , 0xbb80);
    726 
    727 
     931    ichac97MixerStore(pThis, AC97_Vendor_ID1              , 0x8384);
     932    ichac97MixerStore(pThis, AC97_Vendor_ID2              , 0x7600); /* 7608 */
     933
     934    ichac97MixerStore(pThis, AC97_Extended_Audio_ID       , 0x0809);
     935    ichac97MixerStore(pThis, AC97_Extended_Audio_Ctrl_Stat, 0x0009);
     936    ichac97MixerStore(pThis, AC97_PCM_Front_DAC_Rate      , 0xbb80);
     937    ichac97MixerStore(pThis, AC97_PCM_Surround_DAC_Rate   , 0xbb80);
     938    ichac97MixerStore(pThis, AC97_PCM_LFE_DAC_Rate        , 0xbb80);
     939    ichac97MixerStore(pThis, AC97_PCM_LR_ADC_Rate         , 0xbb80);
     940    ichac97MixerStore(pThis, AC97_MIC_ADC_Rate            , 0xbb80);
    728941
    729942#ifdef USE_MIXER
    730     record_select(pThis, 0);
    731     set_volume(pThis, AC97_Master_Volume_Mute,  AUD_MIXER_VOLUME,  0x8000);
    732     set_volume(pThis, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM,     0x8808);
    733     set_volume(pThis, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808);
    734 #else
    735     mixer_store(pThis, AC97_Record_Select, 0);
    736     mixer_store(pThis, AC97_Master_Volume_Mute,  0x8000);
    737     mixer_store(pThis, AC97_PCM_Out_Volume_Mute, 0x8808);
    738     mixer_store(pThis, AC97_Line_In_Volume_Mute, 0x8808);
     943    ichac97RecordSelect(pThis, 0);
     944# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     945    ichac97SetVolume(pThis, AC97_Master_Volume_Mute,  PDMAUDIOMIXERCTL_VOLUME,  0x8000);
     946    ichac97SetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_PCM,     0x8808);
     947    ichac97SetVolume(pThis, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN, 0x8808);
     948# else
     949    ichac97SetVolume(pThis, AC97_Master_Volume_Mute,  AUD_MIXER_VOLUME,  0x8000);
     950    ichac97SetVolume(pThis, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM,     0x8808);
     951    ichac97SetVolume(pThis, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808);
     952# endif
     953#else
     954    ichac97MixerStore(pThis, AC97_Record_Select, 0);
     955    ichac97MixerStore(pThis, AC97_Master_Volume_Mute,  0x8000);
     956    ichac97MixerStore(pThis, AC97_PCM_Out_Volume_Mute, 0x8808);
     957    ichac97MixerStore(pThis, AC97_Line_In_Volume_Mute, 0x8808);
    739958#endif
    740959
    741     reset_voices(pThis, active);
    742 }
    743 
    744 static int write_audio(PAC97STATE pThis, PAC97BMREG pReg, int max, int *stop)
     960#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     961    int rc2 = audioMixerCreate("AC'97 Mixer", 0 /* uFlags */,
     962                               &pThis->pMixer);
     963    if (RT_SUCCESS(rc2))
     964    {
     965        PDMAUDIOSTREAMCFG streamCfg;
     966        streamCfg.uHz           = 48000;
     967        streamCfg.cChannels     = 2;
     968        streamCfg.enmFormat     = AUD_FMT_S16;
     969        streamCfg.enmEndianness = PDMAUDIOHOSTENDIANESS;
     970
     971        rc2 = audioMixerSetDeviceFormat(pThis->pMixer, &streamCfg);
     972        AssertRC(rc2);
     973
     974        /* Add all required audio sinks. */
     975        rc2 = audioMixerAddSink(pThis->pMixer, "[Recording] Line In",
     976                                &pThis->pSinkLineIn);
     977        AssertRC(rc2);
     978
     979        rc2 = audioMixerAddSink(pThis->pMixer, "[Recording] Microphone In",
     980                                &pThis->pSinkMicIn);
     981        AssertRC(rc2);
     982    }
     983#endif
     984
     985    /* Reset all streams. */
     986    uint8_t active[LAST_INDEX] = { 0 };
     987    ichac97ResetStreams(pThis, active);
     988}
     989
     990static int ichac97WriteAudio(PAC97STATE pThis, PAC97BMREG pReg, int max, int *stop)
    745991{
    746992    PPDMDEVINS  pDevIns = ICHAC97STATE_2_DEVINS(pThis);
    747     uint8_t     tmpbuf[4096];
     993
     994    uint8_t     tmpbuf[_4K];
    748995    uint32_t    addr = pReg->bd.addr;
    749     uint32_t    temp = pReg->picb << 1;
    750996    uint32_t    written = 0;
    751     int         to_copy = 0;
    752 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    753     /* count of bytes left in buf to read = samples left in buffer (each of 16 bit) to read denoted by picb * 2) */
    754     uint32_t    cbToRead = pReg->picb << 1;
    755     uint32_t    cbMinToRead;
    756     uint8_t     tmpbufCopy[4096];
    757     int    lun = 0;
    758     uint32_t    slowestLun;
    759     uint32_t    cSamplesLeft;
    760 #endif
    761 
    762     temp = audio_MIN(temp, (uint32_t)max);
     997    uint32_t    to_copy = 0;
     998
     999    uint32_t temp = RT_MIN((pReg->picb << 1), (uint32_t)max);
    7631000    if (!temp)
    7641001    {
     
    7671004    }
    7681005
     1006    int rc = VINF_SUCCESS;
     1007
    7691008    while (temp)
    7701009    {
    771         int copied;
    772         to_copy = audio_MIN(temp, sizeof(tmpbuf));
    773         PDMDevHlpPhysRead(pDevIns, addr, tmpbuf, to_copy);
    774 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    775         /* save a copy of the audio samples read */
    776         memcpy(tmpbufCopy, tmpbuf, to_copy);
    777         uint32_t slowlun = 0;
    778         for (lun = 0; lun < 2; lun++)
    779         {
    780             LogFlow(("DevIchAC97: write_audio to_copy = %d LUN##%d\n", to_copy, lun));
    781             copied = pThis->pDrv[lun]->pfnWrite(pThis->pDrv[lun], pThis->voice_po[lun], tmpbuf, to_copy);
    782             /* call pfnwrite with the same data that has been read from the guest physical memory */
    783             LogFlow(("DevIchAC97: write_audio copied = %d\n", copied));
    784         }
     1010        uint32_t copied;
     1011        to_copy = RT_MIN(temp, sizeof(tmpbuf));
     1012        PDMDevHlpPhysRead(pDevIns, addr, tmpbuf, to_copy); /** @todo Check rc? */
     1013
     1014#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1015# ifdef DEBUG_LUN
     1016        uint8_t lun = DEBUG_LUN_NUM;
     1017# else
     1018        /* Just multiplex the output to the connected backends.
     1019         * No need to utilize the virtual mixer here (yet). */
     1020        for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     1021        {
     1022# endif
     1023            rc = pThis->paDrv[lun]->pConnector->pfnWrite(pThis->paDrv[lun]->pConnector,
     1024                                                         pThis->paDrv[lun]->pStrmOut,
     1025                                                         tmpbuf, to_copy, &copied);
     1026            if (RT_FAILURE(rc))
     1027                continue;
     1028# ifndef DEBUG_LUN
     1029        }
     1030# endif
    7851031#else
    7861032        copied = AUD_write(pThis->voice_po, tmpbuf, to_copy);
    787 #endif
     1033#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1034        LogRelFunc(("to_copy=%RU32, copied=%RU32, temp=%RU32, temp_left=%RU32\n", to_copy, copied,
     1035                    temp, temp - copied));
     1036
    7881037        if (!copied)
    7891038        {
     
    8001049        if (to_copy < 4)
    8011050        {
    802             Log(("ac97: whoops\n"));
     1051            LogFlowFunc(("whoops\n"));
    8031052            pThis->last_samp = 0;
    8041053        }
     
    8081057
    8091058    pReg->bd.addr = addr;
     1059
     1060    LogRelFunc(("written=%RU32\n", written));
    8101061    return written;
    8111062}
    8121063
    813 static void write_bup(PAC97STATE pThis, int elapsed)
    814 {
    815     int written = 0;
    816     Log(("ac97: write_bup\n"));
     1064static void ichac97WriteBUP(PAC97STATE pThis, int elapsed)
     1065{
    8171066    if (!(pThis->bup_flag & BUP_SET))
    8181067    {
     
    8251074        }
    8261075        else
    827             memset(pThis->silence, 0, sizeof(pThis->silence));
     1076            RT_ZERO(pThis->silence);
    8281077
    8291078        pThis->bup_flag |= BUP_SET;
    8301079    }
    8311080
     1081    int written = 0;
     1082
    8321083    while (elapsed)
    8331084    {
    834         unsigned int temp = audio_MIN((unsigned int)elapsed, sizeof(pThis->silence));
    835         int copied;
     1085        unsigned int temp = RT_MIN((unsigned int)elapsed, sizeof(pThis->silence));
     1086        uint32_t copied;
    8361087        while (temp)
    8371088        {
    8381089#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    839             for (int lun = 0; lun < 2; lun++)
     1090# ifdef DEBUG_LUN
     1091            uint8_t lun = DEBUG_LUN_NUM;
     1092# else
     1093            for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
    8401094            {
    841                 LogFlow(("DevIchAC97: write_silence LUN##%d , to_copy=%d\n", lun, temp));
    842                 copied = pThis->pDrv[lun]->pfnWrite(pThis->pDrv[lun], pThis->voice_po[lun], pThis->silence, temp);
    843                 LogFlow(("DevIchAC97: write_silence LUN##%d , copied=%d\n", lun, copied));
     1095# endif
     1096                int rc2 = pThis->paDrv[lun]->pConnector->pfnWrite(pThis->paDrv[lun]->pConnector,
     1097                                                                  pThis->paDrv[lun]->pStrmOut,
     1098                                                                  pThis->silence, temp, &copied);
     1099                if (RT_FAILURE(rc2))
     1100                    continue;
     1101# ifndef DEBUG_LUN
    8441102            }
     1103# endif
    8451104#else
    8461105            copied = AUD_write(pThis->voice_po, pThis->silence, temp);
    847 #endif
     1106#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1107
    8481108            if (!copied)
    8491109                return;
     
    8551115}
    8561116
    857 static int read_audio(PAC97STATE pThis, PAC97BMREG pReg, int max, int *stop)
     1117static int ichac97ReadAudio(PAC97STATE pThis, PAC97BMREG pReg, int max, int *stop)
    8581118{
    8591119    PPDMDEVINS  pDevIns = ICHAC97STATE_2_DEVINS(pThis);
    8601120
     1121#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1122    /* Select audio sink to process. */
     1123    PAUDMIXSINK pSink = (pReg - pThis->bm_regs) == MC_INDEX
     1124                      ? pThis->pSinkMicIn : pThis->pSinkLineIn;
     1125    AssertPtr(pSink);
     1126
     1127    int rc;
     1128    uint32_t cbRead;
     1129
     1130    size_t cbMixBuf = max * sizeof(uint8_t);
     1131    Assert(cbMixBuf);
     1132    uint32_t cbToRead = RT_MIN(pReg->picb << 1, cbMixBuf);
     1133
     1134    uint8_t *pvMixBuf = (uint8_t *)RTMemAlloc(cbMixBuf);
     1135    if (pvMixBuf)
     1136    {
     1137        rc = audioMixerProcessSinkIn(pSink, pvMixBuf, cbToRead, &cbRead);
     1138        if (   RT_SUCCESS(rc)
     1139            && cbRead)
     1140        {
     1141            PDMDevHlpPCIPhysWrite(pDevIns, pReg->bd.addr, pvMixBuf, cbRead);
     1142            pReg->bd.addr += cbRead;
     1143        }
     1144        else
     1145            *stop = 1;
     1146
     1147        RTMemFree(pvMixBuf);
     1148    }
     1149    else
     1150        *stop = 1;
     1151
     1152    if (*stop)
     1153        cbRead = 0;
     1154
     1155    return cbRead;
     1156#else
    8611157    uint32_t    addr = pReg->bd.addr;
    8621158    uint32_t    temp = pReg->picb << 1;
    8631159    uint32_t    nread = 0;
    8641160    int         to_copy = 0;
    865 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    866     uint8_t     u8DupBuf[4096];
    867     PDMHOSTSTEREOSAMPLE     tmpbuf[4096];
    868     PDMHOSTSTEREOSAMPLE MixBuf[2000];
    869     PDMHOSTSTEREOSAMPLE InputBuf[2000];
    870     PPDMHOSTSTEREOSAMPLE SrcBuf;
    871     uint32_t    cSamplesMixed = 0;
    872     uint32_t    cTotalSamplesMixed = 0;
    873     uint32_t    cSamplesRead = 0;
    874     uint32_t    offRead = 0;
    875     uint32_t    offWrite = 0;
    876     uint32_t    cTotalSamplesRead = 0;
    877     uint32_t isamp = 0, osamp = 0;
    878     uint32_t lun =0;
    879     PPDMGSTVOICEIN voice[2];
    880     memset(MixBuf, 0, sizeof(MixBuf));
    881     memset(InputBuf, 0, sizeof(InputBuf));
    882     memset(u8DupBuf, 0, sizeof(u8DupBuf));
    883     void * rate[2];
    884 
    885     for (lun = 0; lun < 2; lun++)
    886         voice[lun] = (pReg - pThis->bm_regs) == MC_INDEX ? pThis->voice_mc[lun] : pThis->voice_pi[lun];
    887 #else
     1161
    8881162    SWVoiceIn  *voice = (pReg - pThis->bm_regs) == MC_INDEX ? pThis->voice_mc : pThis->voice_pi;
    889 #endif
    8901163
    8911164    temp = audio_MIN(temp, (uint32_t)max);
     
    8961169    }
    8971170
    898 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    899     rate[0] = pThis->pDrv[0]->pfnPrepareAudioConversion(pThis->pDrv[0], 48000, 48000);
    900     //rate[1] = pThis->pDrv[1]->pfnPrepareAudioConversion(pThis->pDrv[1], 22100, 22100);
    901     rate[1] = pThis->pDrv[1]->pfnPrepareAudioConversion(pThis->pDrv[1], 48000, 48000);
    902     for (lun = 0; lun < 2; lun++)
    903     {
    904         temp = pReg->picb << 1;
    905         temp = audio_MIN(temp, (uint32_t)max);
    906         LogFlow(("DevIchAC97: temp = %d and max = %d\n", temp, max));
    907         if (!temp)
    908         {
    909             *stop = 1;
    910             return 0;
    911         }
    912         memset(tmpbuf, 0, sizeof(tmpbuf));
    913         offRead = 0;
    914         offWrite = 0;
    915         cSamplesMixed = 0;
    916         nread = 0;
    917         while (temp)
    918         {
    919             int acquired;
    920             to_copy = audio_MIN(temp, sizeof(tmpbuf));
    921             acquired = pThis->pDrv[lun]->pfnRead(pThis->pDrv[lun], voice[lun], tmpbuf, to_copy);
    922             cSamplesRead = acquired >> voice[lun]->Props.cShift;
    923             while (cSamplesRead)
    924             {
    925                 SrcBuf = tmpbuf + offRead;
    926                 isamp = cSamplesRead;
    927                 if (!isamp)
    928                 {
    929                     LogFlow(("DevichAC97: No Input samples \n"));
    930                     break;
    931                 }
    932                 osamp = cSamplesRead - cSamplesMixed; /*sizeof(MixBuf)*/;
    933                 pThis->pDrv[lun]->pfnDoRateConvAndMix(pThis->pDrv[lun], rate[lun], SrcBuf,
    934                                                     MixBuf, &isamp, &osamp);
    935                 cSamplesRead -= isamp;
    936                 offRead += isamp;
    937                 offWrite += osamp;
    938                 cSamplesMixed += isamp;
    939             }
    940             if (!acquired)
    941             {
    942                 *stop = 1;
    943                 break;
    944             }
    945             pThis->pDrv[lun]->pfnConvStSampleToDevFmt(pThis->pDrv[lun], u8DupBuf, MixBuf, cSamplesMixed);
    946             temp  -= acquired;
    947             //addr  += acquired;
    948             //addr  += (ctotalSamplexMixed << voice->Props.cShift);
    949             //nread += (cSamplesMixed << voice->Props.cShift);
    950             nread += acquired;
    951             LogFlow(("DevIchAC97: looping temp = %d\n", temp));
    952             cTotalSamplesRead = audio_MAX(cTotalSamplesRead, nread);
    953             cTotalSamplesMixed = audio_MAX(cTotalSamplesMixed, cSamplesMixed);
    954         }
    955     }
    956     if (cTotalSamplesMixed)
    957         PDMDevHlpPCIPhysWrite(pDevIns, addr, u8DupBuf, (cTotalSamplesMixed << voice[0]->Props.cShift));
    958     addr  += (cTotalSamplesMixed << voice[0]->Props.cShift);
    959     nread = cTotalSamplesRead;
    960 #else
    9611171    uint8_t tmpbuf[4096];
    9621172    while (temp)
     
    9751185        nread += acquired;
    9761186    }
    977 #endif
     1187
    9781188    pReg->bd.addr = addr;
    9791189    return nread;
    980 }
    981 
    982 static void transfer_audio(PAC97STATE pThis, int index, int elapsed)
    983 {
     1190#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1191}
     1192
     1193#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1194static void ichac97TransferAudio(PAC97DRIVER pDrv, int index, int elapsed)
     1195#else
     1196static void ichac97TransferAudio(PAC97STATE pThis, int index, int elapsed)
     1197#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1198{
     1199#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1200    PAC97STATE pThis = pDrv->pAC97State;
     1201
     1202    if (pDrv->uLUN != 0) /* Only LUN 0 can write and read from the device. */
     1203        return;
     1204    /** @todo Fix this limitation by implementing a virtual mixer. */
     1205#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1206
    9841207    PAC97BMREG pReg = &pThis->bm_regs[index];
    985     int written = 0;
    986     int stop = 0;
    987 
    988     if (pReg->sr & SR_DCH)
     1208    if (pReg->sr & SR_DCH) /* Controller halted? */
    9891209    {
    9901210        if (pReg->cr & CR_RPBM)
     
    9931213            {
    9941214                case PO_INDEX:
    995                     write_bup(pThis, elapsed);
     1215                    ichac97WriteBUP(pThis, elapsed);
     1216                    break;
     1217
     1218                default:
    9961219                    break;
    9971220            }
    9981221        }
     1222
    9991223        return;
    10001224    }
    10011225
     1226    int written = 0;
     1227    int stop = 0;
     1228
    10021229    while ((elapsed >> 1) && !stop)
    10031230    {
     
    10061233        if (!pReg->bd_valid)
    10071234        {
    1008             Log(("ac97: invalid bd\n"));
    1009             fetch_bd(pThis, pReg);
    1010         }
    1011 
    1012         if (!pReg->picb)
    1013         {
    1014             Log(("ac97: fresh bd %d is empty %#x %#x, skipping\n", pReg->civ, pReg->bd.addr, pReg->bd.ctl_len));
     1235            LogFlowFunc(("Invalid buffer descriptor, fetching next one ...\n"));
     1236            ichac97FetchBufDesc(pThis, pReg);
     1237        }
     1238
     1239        if (!pReg->picb) /* Got a new buffer descriptor, that is, the position is 0? */
     1240        {
     1241            LogFlowFunc(("Fresh buffer descriptor %d is empty, addr=%#x, len=%#x, skipping\n",
     1242                         pReg->civ, pReg->bd.addr, pReg->bd.ctl_len));
    10151243            if (pReg->civ == pReg->lvi)
    10161244            {
     
    10191247                break;
    10201248            }
     1249
    10211250            pReg->sr &= ~SR_CELV;
    10221251            pReg->civ = pReg->piv;
    10231252            pReg->piv = (pReg->piv + 1) % 32;
    1024             fetch_bd(pThis, pReg);
     1253
     1254            ichac97FetchBufDesc(pThis, pReg);
    10251255            continue;
    10261256        }
     
    10291259        {
    10301260            case PO_INDEX:
    1031                 temp = write_audio(pThis, pReg, elapsed, &stop);
     1261                temp = ichac97WriteAudio(pThis, pReg, elapsed, &stop);
    10321262                written += temp;
    10331263                elapsed -= temp;
     
    10381268            case PI_INDEX:
    10391269            case MC_INDEX:
    1040                 temp = read_audio(pThis, pReg, elapsed, &stop);
     1270                temp = ichac97ReadAudio(pThis, pReg, elapsed, &stop);
    10411271                elapsed -= temp;
    10421272                Assert((temp & 1) == 0);    /* Else the following shift won't work */
    10431273                pReg->picb -= (temp >> 1);
    10441274                break;
    1045         }
    1046         Log(("pReg->picb = %d\n", pReg->picb));
     1275
     1276            default:
     1277                AssertMsgFailed(("Index %d not supported\n", index));
     1278                break;
     1279        }
     1280        LogFlowFunc(("pReg->picb = %d\n", pReg->picb));
    10471281
    10481282        if (!pReg->picb)
     
    10571291            if (pReg->civ == pReg->lvi)
    10581292            {
    1059                 Log(("ac97: Underrun civ (%d) == lvi (%d)\n", pReg->civ, pReg->lvi));
     1293                LogFlowFunc(("Underrun civ (%d) == lvi (%d)\n", pReg->civ, pReg->lvi));
    10601294                new_sr |= SR_LVBCI | SR_DCH | SR_CELV;
    10611295                stop = 1;
     
    10661300                pReg->civ = pReg->piv;
    10671301                pReg->piv = (pReg->piv + 1) % 32;
    1068                 fetch_bd(pThis, pReg);
     1302                ichac97FetchBufDesc(pThis, pReg);
    10691303            }
    1070             update_sr(pThis, pReg, new_sr);
    1071         }
    1072     }
    1073 }
    1074 
    1075 static void pi_callback(void *opaque, int avail)
    1076 {
    1077     transfer_audio((AC97STATE *)opaque, PI_INDEX, avail);
    1078 }
    1079 
    1080 static void mc_callback(void *opaque, int avail)
    1081 {
    1082     transfer_audio((AC97STATE *)opaque, MC_INDEX, avail);
    1083 }
    1084 
    1085 static void po_callback(void *opaque, int free)
    1086 {
    1087     transfer_audio((AC97STATE *)opaque, PO_INDEX, free);
    1088 }
     1304
     1305            ichac97UpdateStatus(pThis, pReg, new_sr);
     1306        }
     1307    }
     1308}
     1309
     1310#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1311static void ichac97InputCallback(void *pvContext, uint32_t cbAvail)
     1312{
     1313    PAC97DRIVER pThis = (PAC97DRIVER)pvContext;
     1314    ichac97TransferAudio(pThis, PI_INDEX, cbAvail);
     1315}
     1316#else
     1317static void ichac97InputCallback(void *pvContext, int cbAvail)
     1318{
     1319    ichac97TransferAudio((AC97STATE *)pvContext, PI_INDEX, cbAvail);
     1320}
     1321#endif
     1322
     1323#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1324static void ichac97MicInCallback(void *pvContext, uint32_t cbAvail)
     1325{
     1326    PAC97DRIVER pThis = (PAC97DRIVER)pvContext;
     1327    ichac97TransferAudio(pThis, MC_INDEX, cbAvail);
     1328}
     1329#else
     1330static void ichac97MicInCallback(void *pvContext, int cbAvail)
     1331{
     1332    ichac97TransferAudio((AC97STATE *)pvContext, MC_INDEX, cbAvail);
     1333}
     1334#endif
     1335
     1336#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1337static void ichac97OutputCallback(void *pvContext, uint32_t cbFree)
     1338{
     1339    PAC97DRIVER pThis = (PAC97DRIVER)pvContext;
     1340    ichac97TransferAudio(pThis, PO_INDEX, cbFree);
     1341}
     1342#else
     1343static void ichac97OutputCallback(void *pvContext, int cbFree)
     1344{
     1345    ichac97TransferAudio((AC97STATE *)pvContext, PO_INDEX, cbFree);
     1346}
     1347#endif
    10891348
    10901349/**
     
    11071366                case CAS:
    11081367                    /* Codec Access Semaphore Register */
    1109                     Log(("ac97: CAS %d\n", pThis->cas));
     1368                    LogFlowFunc(("CAS %d\n", pThis->cas));
    11101369                    *pu32 = pThis->cas;
    11111370                    pThis->cas = 1;
     
    11171376                    pReg = &pThis->bm_regs[GET_BM(index)];
    11181377                    *pu32 = pReg->civ;
    1119                     Log(("ac97: CIV[%d] -> %#x\n", GET_BM(index), *pu32));
     1378                    LogFlowFunc(("CIV[%d] -> %#x\n", GET_BM(index), *pu32));
    11201379                    break;
    11211380                case PI_LVI:
     
    11251384                    pReg = &pThis->bm_regs[GET_BM(index)];
    11261385                    *pu32 = pReg->lvi;
    1127                     Log(("ac97: LVI[%d] -> %#x\n", GET_BM(index), *pu32));
     1386                    LogFlowFunc(("LVI[%d] -> %#x\n", GET_BM(index), *pu32));
    11281387                    break;
    11291388                case PI_PIV:
     
    11331392                    pReg = &pThis->bm_regs[GET_BM(index)];
    11341393                    *pu32 = pReg->piv;
    1135                     Log(("ac97: PIV[%d] -> %#x\n", GET_BM(index), *pu32));
     1394                    LogFlowFunc(("PIV[%d] -> %#x\n", GET_BM(index), *pu32));
    11361395                    break;
    11371396                case PI_CR:
     
    11411400                    pReg = &pThis->bm_regs[GET_BM(index)];
    11421401                    *pu32 = pReg->cr;
    1143                     Log(("ac97: CR[%d] -> %#x\n", GET_BM(index), *pu32));
     1402                    LogFlowFunc(("CR[%d] -> %#x\n", GET_BM(index), *pu32));
    11441403                    break;
    11451404                case PI_SR:
     
    11491408                    pReg = &pThis->bm_regs[GET_BM(index)];
    11501409                    *pu32 = pReg->sr & 0xff;
    1151                     Log(("ac97: SRb[%d] -> %#x\n", GET_BM(index), *pu32));
     1410                    LogFlowFunc(("SRb[%d] -> %#x\n", GET_BM(index), *pu32));
    11521411                    break;
    11531412                default:
    1154                     Log(("ac97: U nabm readb %#x -> %#x\n", Port, *pu32));
     1413                    LogFlowFunc(("U nabm readb %#x -> %#x\n", Port, *pu32));
    11551414                    break;
    11561415            }
     
    11721431                    pReg = &pThis->bm_regs[GET_BM(index)];
    11731432                    *pu32 = pReg->sr;
    1174                     Log(("ac97: SR[%d] -> %#x\n", GET_BM(index), *pu32));
     1433                    LogFlowFunc(("SR[%d] -> %#x\n", GET_BM(index), *pu32));
    11751434                    break;
    11761435                case PI_PICB:
     
    11801439                    pReg = &pThis->bm_regs[GET_BM(index)];
    11811440                    *pu32 = pReg->picb;
    1182                     Log(("ac97: PICB[%d] -> %#x\n", GET_BM(index), *pu32));
     1441                    LogFlowFunc(("PICB[%d] -> %#x\n", GET_BM(index), *pu32));
    11831442                    break;
    11841443                default:
    1185                     Log(("ac97: U nabm readw %#x -> %#x\n", Port, *pu32));
     1444                    LogFlowFunc(("U nabm readw %#x -> %#x\n", Port, *pu32));
    11861445                    break;
    11871446            }
     
    12031462                    pReg = &pThis->bm_regs[GET_BM(index)];
    12041463                    *pu32 = pReg->bdbar;
    1205                     Log(("ac97: BMADDR[%d] -> %#x\n", GET_BM(index), *pu32));
     1464                    LogFlowFunc(("BMADDR[%d] -> %#x\n", GET_BM(index), *pu32));
    12061465                    break;
    12071466                case PI_CIV:
     
    12131472                    pReg = &pThis->bm_regs[GET_BM(index)];
    12141473                    *pu32 = pReg->civ | (pReg->lvi << 8) | (pReg->sr << 16);
    1215                     Log(("ac97: CIV LVI SR[%d] -> %#x, %#x, %#x\n", GET_BM(index), pReg->civ, pReg->lvi, pReg->sr));
     1474                    LogFlowFunc(("CIV LVI SR[%d] -> %#x, %#x, %#x\n", GET_BM(index), pReg->civ, pReg->lvi, pReg->sr));
    12161475                    break;
    12171476                case PI_PICB:
     
    12231482                    pReg = &pThis->bm_regs[GET_BM(index)];
    12241483                    *pu32 = pReg->picb | (pReg->piv << 16) | (pReg->cr << 24);
    1225                     Log(("ac97: PICB PIV CR[%d] -> %#x %#x %#x %#x\n", GET_BM(index), *pu32, pReg->picb, pReg->piv, pReg->cr));
     1484                    LogFlowFunc(("PICB PIV CR[%d] -> %#x %#x %#x %#x\n", GET_BM(index), *pu32, pReg->picb, pReg->piv, pReg->cr));
    12261485                    break;
    12271486                case GLOB_CNT:
    12281487                    /* Global Control */
    12291488                    *pu32 = pThis->glob_cnt;
    1230                     Log(("ac97: glob_cnt -> %#x\n", *pu32));
     1489                    LogFlowFunc(("glob_cnt -> %#x\n", *pu32));
    12311490                    break;
    12321491                case GLOB_STA:
    12331492                    /* Global Status */
    12341493                    *pu32 = pThis->glob_sta | GS_S0CR;
    1235                     Log(("ac97: glob_sta -> %#x\n", *pu32));
     1494                    LogFlowFunc(("glob_sta -> %#x\n", *pu32));
    12361495                    break;
    12371496                default:
    1238                     Log(("ac97: U nabm readl %#x -> %#x\n", Port, *pu32));
     1497                    LogFlowFunc(("U nabm readl %#x -> %#x\n", Port, *pu32));
    12391498                    break;
    12401499            }
     
    12731532                        pReg->civ = pReg->piv;
    12741533                        pReg->piv = (pReg->piv + 1) % 32;
    1275                         fetch_bd(pThis, pReg);
     1534                        ichac97FetchBufDesc(pThis, pReg);
    12761535                    }
    12771536                    pReg->lvi = u32 % 32;
    1278                     Log(("ac97: LVI[%d] <- %#x\n", GET_BM(index), u32));
     1537                    LogFlowFunc(("LVI[%d] <- %#x\n", GET_BM(index), u32));
    12791538                    break;
    12801539                case PI_CR:
     
    12841543                    pReg = &pThis->bm_regs[GET_BM(index)];
    12851544                    if (u32 & CR_RR)
    1286                         reset_bm_regs(pThis, pReg);
     1545                        ichac97ResetBMRegs(pThis, pReg);
    12871546                    else
    12881547                    {
     
    12901549                        if (!(pReg->cr & CR_RPBM))
    12911550                        {
    1292                             voice_set_active(pThis, pReg - pThis->bm_regs, 0);
     1551                            ichac97StreamSetActive(pThis, pReg - pThis->bm_regs, 0);
    12931552                            pReg->sr |= SR_DCH;
    12941553                        }
     
    12971556                            pReg->civ = pReg->piv;
    12981557                            pReg->piv = (pReg->piv + 1) % 32;
    1299                             fetch_bd(pThis, pReg);
     1558                            ichac97FetchBufDesc(pThis, pReg);
    13001559                            pReg->sr &= ~SR_DCH;
    1301                             voice_set_active(pThis, pReg - pThis->bm_regs, 1);
     1560                            ichac97StreamSetActive(pThis, pReg - pThis->bm_regs, 1);
    13021561                        }
    13031562                    }
    1304                     Log(("ac97: CR[%d] <- %#x (cr %#x)\n", GET_BM(index), u32, pReg->cr));
     1563                    LogFlowFunc(("CR[%d] <- %#x (cr %#x)\n", GET_BM(index), u32, pReg->cr));
    13051564                    break;
    13061565                case PI_SR:
     
    13101569                    pReg = &pThis->bm_regs[GET_BM(index)];
    13111570                    pReg->sr |= u32 & ~(SR_RO_MASK | SR_WCLEAR_MASK);
    1312                     update_sr(pThis, pReg, pReg->sr & ~(u32 & SR_WCLEAR_MASK));
    1313                     Log(("ac97: SR[%d] <- %#x (sr %#x)\n", GET_BM(index), u32, pReg->sr));
     1571                    ichac97UpdateStatus(pThis, pReg, pReg->sr & ~(u32 & SR_WCLEAR_MASK));
     1572                    LogFlowFunc(("SR[%d] <- %#x (sr %#x)\n", GET_BM(index), u32, pReg->sr));
    13141573                    break;
    13151574                default:
    1316                     Log(("ac97: U nabm writeb %#x <- %#x\n", Port, u32));
     1575                    LogFlowFunc(("U nabm writeb %#x <- %#x\n", Port, u32));
    13171576                    break;
    13181577            }
     
    13321591                    pReg = &pThis->bm_regs[GET_BM(index)];
    13331592                    pReg->sr |= u32 & ~(SR_RO_MASK | SR_WCLEAR_MASK);
    1334                     update_sr(pThis, pReg, pReg->sr & ~(u32 & SR_WCLEAR_MASK));
    1335                     Log(("ac97: SR[%d] <- %#x (sr %#x)\n", GET_BM(index), u32, pReg->sr));
     1593                    ichac97UpdateStatus(pThis, pReg, pReg->sr & ~(u32 & SR_WCLEAR_MASK));
     1594                    LogFlowFunc(("SR[%d] <- %#x (sr %#x)\n", GET_BM(index), u32, pReg->sr));
    13361595                    break;
    13371596                default:
    1338                     Log(("ac97: U nabm writew %#x <- %#x\n", Port, u32));
     1597                    LogFlowFunc(("U nabm writew %#x <- %#x\n", Port, u32));
    13391598                    break;
    13401599            }
     
    13541613                    pReg = &pThis->bm_regs[GET_BM(index)];
    13551614                    pReg->bdbar = u32 & ~3;
    1356                     Log(("ac97: BDBAR[%d] <- %#x (bdbar %#x)\n", GET_BM(index), u32, pReg->bdbar));
     1615                    LogFlowFunc(("BDBAR[%d] <- %#x (bdbar %#x)\n", GET_BM(index), u32, pReg->bdbar));
    13571616                    break;
    13581617                case GLOB_CNT:
    13591618                    /* Global Control */
    13601619                    if (u32 & GC_WR)
    1361                         warm_reset(pThis);
     1620                        ichac97WarmReset(pThis);
    13621621                    if (u32 & GC_CR)
    1363                         cold_reset(pThis);
     1622                        ichac97ColdReset(pThis);
    13641623                    if (!(u32 & (GC_WR | GC_CR)))
    13651624                        pThis->glob_cnt = u32 & GC_VALID_MASK;
    1366                     Log(("ac97: glob_cnt <- %#x (glob_cnt %#x)\n", u32, pThis->glob_cnt));
     1625                    LogFlowFunc(("glob_cnt <- %#x (glob_cnt %#x)\n", u32, pThis->glob_cnt));
    13671626                    break;
    13681627                case GLOB_STA:
     
    13701629                    pThis->glob_sta &= ~(u32 & GS_WCLEAR_MASK);
    13711630                    pThis->glob_sta |= (u32 & ~(GS_WCLEAR_MASK | GS_RO_MASK)) & GS_VALID_MASK;
    1372                     Log(("ac97: glob_sta <- %#x (glob_sta %#x)\n", u32, pThis->glob_sta));
     1631                    LogFlowFunc(("glob_sta <- %#x (glob_sta %#x)\n", u32, pThis->glob_sta));
    13731632                    break;
    13741633                default:
    1375                     Log(("ac97: U nabm writel %#x <- %#x\n", Port, u32));
     1634                    LogFlowFunc(("U nabm writel %#x <- %#x\n", Port, u32));
    13761635                    break;
    13771636            }
     
    13971656        case 1:
    13981657        {
    1399             Log(("ac97: U nam readb %#x\n", Port));
     1658            LogFlowFunc(("U nam readb %#x\n", Port));
    14001659            pThis->cas = 0;
    14011660            *pu32 = ~0U;
     
    14111670            {
    14121671                default:
    1413                     *pu32 = mixer_load(pThis, index);
    1414                     Log(("ac97: nam readw %#x -> %#x\n", Port, *pu32));
     1672                    *pu32 = ichac97MixerLoad(pThis, index);
     1673                    LogFlowFunc(("nam readw %#x -> %#x\n", Port, *pu32));
    14151674                    break;
    14161675            }
     
    14201679        case 4:
    14211680        {
    1422             Log(("ac97: U nam readl %#x\n", Port));
     1681            LogFlowFunc(("U nam readl %#x\n", Port));
    14231682            pThis->cas = 0;
    14241683            *pu32 = ~0U;
     
    14351694 * @callback_method_impl{FNIOMIOPORTOUT}
    14361695 */
    1437 static DECLCALLBACK(int) ichac97IOPortNAMWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
     1696static DECLCALLBACK(int) ichac97IOPortNAMWrite(PPDMDEVINS pDevIns,
     1697                                               void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
    14381698{
    14391699    PAC97STATE pThis = (PAC97STATE)pvUser;
     
    14431703        case 1:
    14441704        {
    1445             Log(("ac97: U nam writeb %#x <- %#x\n", Port, u32));
     1705            LogFlowFunc(("U nam writeb %#x <- %#x\n", Port, u32));
    14461706            pThis->cas = 0;
    14471707            break;
     
    14551715            {
    14561716                case AC97_Reset:
    1457                     mixer_reset(pThis);
     1717                    ichac97MixerReset(pThis);
    14581718                    break;
    14591719                case AC97_Powerdown_Ctrl_Stat:
    14601720                    u32 &= ~0xf;
    1461                     u32 |= mixer_load(pThis, index) & 0xf;
    1462                     mixer_store(pThis, index, u32);
     1721                    u32 |= ichac97MixerLoad(pThis, index) & 0xf;
     1722                    ichac97MixerStore(pThis, index, u32);
    14631723                    break;
    14641724#ifdef USE_MIXER
    14651725                case AC97_Master_Volume_Mute:
    1466                     set_volume(pThis, index, AUD_MIXER_VOLUME, u32);
     1726#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1727                    ichac97SetVolume(pThis, index, PDMAUDIOMIXERCTL_VOLUME, u32);
     1728#else
     1729                    ichac97SetVolume(pThis, index, AUD_MIXER_VOLUME, u32);
     1730#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    14671731                    break;
    14681732                case AC97_PCM_Out_Volume_Mute:
    1469                     set_volume(pThis, index, AUD_MIXER_PCM, u32);
     1733#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1734                    ichac97SetVolume(pThis, index, PDMAUDIOMIXERCTL_PCM, u32);
     1735#else
     1736                    ichac97SetVolume(pThis, index, AUD_MIXER_PCM, u32);
     1737#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    14701738                    break;
    14711739                case AC97_Line_In_Volume_Mute:
    1472                     set_volume(pThis, index, AUD_MIXER_LINE_IN, u32);
     1740#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1741                    ichac97SetVolume(pThis, index, PDMAUDIOMIXERCTL_LINE_IN, u32);
     1742#else
     1743                    ichac97SetVolume(pThis, index, AUD_MIXER_LINE_IN, u32);
     1744#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    14731745                    break;
    14741746                case AC97_Record_Select:
    1475                     record_select(pThis, u32);
     1747                    ichac97RecordSelect(pThis, u32);
    14761748                    break;
    14771749#else  /* !USE_MIXER */
     
    14801752                case AC97_Line_In_Volume_Mute:
    14811753                case AC97_Record_Select:
    1482                     mixer_store(pThis, index, u32);
     1754                    ichac97MixerStore(pThis, index, u32);
    14831755                    break;
    14841756#endif /* !USE_MIXER */
    14851757                case AC97_Vendor_ID1:
    14861758                case AC97_Vendor_ID2:
    1487                     Log(("ac97: Attempt to write vendor ID to %#x\n", u32));
     1759                    LogFlowFunc(("Attempt to write vendor ID to %#x\n", u32));
    14881760                    break;
    14891761                case AC97_Extended_Audio_ID:
    1490                     Log(("ac97: Attempt to write extended audio ID to %#x\n", u32));
     1762                    LogFlowFunc(("Attempt to write extended audio ID to %#x\n", u32));
    14911763                    break;
    14921764                case AC97_Extended_Audio_Ctrl_Stat:
    14931765                    if (!(u32 & EACS_VRA))
    14941766                    {
    1495                         mixer_store(pThis, AC97_PCM_Front_DAC_Rate, 0xbb80);
    1496                         mixer_store(pThis, AC97_PCM_LR_ADC_Rate,    0xbb80);
    1497                         open_voice(pThis, PI_INDEX, 48000);
    1498                         open_voice(pThis, PO_INDEX, 48000);
     1767                        ichac97MixerStore(pThis, AC97_PCM_Front_DAC_Rate, 0xbb80);
     1768                        ichac97MixerStore(pThis, AC97_PCM_LR_ADC_Rate,    0xbb80);
     1769                        ichac97OpenStream(pThis, PI_INDEX, 48000);
     1770                        ichac97OpenStream(pThis, PO_INDEX, 48000);
    14991771                    }
    15001772                    if (!(u32 & EACS_VRM))
    15011773                    {
    1502                         mixer_store(pThis, AC97_MIC_ADC_Rate, 0xbb80);
    1503                          open_voice(pThis, MC_INDEX, 48000);
     1774                        ichac97MixerStore(pThis, AC97_MIC_ADC_Rate, 0xbb80);
     1775                        ichac97OpenStream(pThis, MC_INDEX, 48000);
    15041776                    }
    1505                     Log(("ac97: Setting extended audio control to %#x\n", u32));
    1506                     mixer_store(pThis, AC97_Extended_Audio_Ctrl_Stat, u32);
     1777                    LogFlowFunc(("Setting extended audio control to %#x\n", u32));
     1778                    ichac97MixerStore(pThis, AC97_Extended_Audio_Ctrl_Stat, u32);
    15071779                    break;
    15081780                case AC97_PCM_Front_DAC_Rate:
    1509                     if (mixer_load(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA)
     1781                    if (ichac97MixerLoad(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA)
    15101782                    {
    1511                         mixer_store(pThis, index, u32);
    1512                         Log(("ac97: Set front DAC rate to %d\n", u32));
    1513                         open_voice(pThis, PO_INDEX, u32);
     1783                        ichac97MixerStore(pThis, index, u32);
     1784                        LogFlowFunc(("Set front DAC rate to %d\n", u32));
     1785                        ichac97OpenStream(pThis, PO_INDEX, u32);
    15141786                    }
    15151787                    else
    1516                         Log(("ac97: Attempt to set front DAC rate to %d, but VRA is not set\n", u32));
     1788                        LogFlowFunc(("Attempt to set front DAC rate to %d, but VRA is not set\n", u32));
    15171789                    break;
    15181790                case AC97_MIC_ADC_Rate:
    1519                     if (mixer_load(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRM)
     1791                    if (ichac97MixerLoad(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRM)
    15201792                    {
    1521                         mixer_store(pThis, index, u32);
    1522                         Log(("ac97: Set MIC ADC rate to %d\n", u32));
    1523                         open_voice(pThis, MC_INDEX, u32);
     1793                        ichac97MixerStore(pThis, index, u32);
     1794                        LogFlowFunc(("Set MIC ADC rate to %d\n", u32));
     1795                        ichac97OpenStream(pThis, MC_INDEX, u32);
    15241796                    }
    15251797                    else
    1526                         Log(("ac97: Attempt to set MIC ADC rate to %d, but VRM is not set\n", u32));
     1798                        LogFlowFunc(("Attempt to set MIC ADC rate to %d, but VRM is not set\n", u32));
    15271799                    break;
    15281800                case AC97_PCM_LR_ADC_Rate:
    1529                     if (mixer_load(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA)
     1801                    if (ichac97MixerLoad(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA)
    15301802                    {
    1531                         mixer_store(pThis, index, u32);
    1532                         Log(("ac97: Set front LR ADC rate to %d\n", u32));
    1533                         open_voice(pThis, PI_INDEX, u32);
     1803                        ichac97MixerStore(pThis, index, u32);
     1804                        LogFlowFunc(("Set front LR ADC rate to %d\n", u32));
     1805                        ichac97OpenStream(pThis, PI_INDEX, u32);
    15341806                    }
    15351807                    else
    1536                         Log(("ac97: Attempt to set LR ADC rate to %d, but VRA is not set\n", u32));
     1808                        LogFlowFunc(("Attempt to set LR ADC rate to %d, but VRA is not set\n", u32));
    15371809                    break;
    15381810                default:
    1539                     Log(("ac97: U nam writew %#x <- %#x\n", Port, u32));
    1540                     mixer_store(pThis, index, u32);
     1811                    LogFlowFunc(("U nam writew %#x <- %#x\n", Port, u32));
     1812                    ichac97MixerStore(pThis, index, u32);
    15411813                    break;
    15421814            }
     
    15461818        case 4:
    15471819        {
    1548             Log(("ac97: U nam writel %#x <- %#x\n", Port, u32));
     1820            LogFlowFunc(("U nam writel %#x <- %#x\n", Port, u32));
    15491821            pThis->cas = 0;
    15501822            break;
     
    15551827            break;
    15561828    }
     1829
    15571830    return VINF_SUCCESS;
    15581831}
     
    16171890
    16181891    uint8_t active[LAST_INDEX];
    1619 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1620     /* writing only host backend values here and ignoring for webm and VRDE */
    1621     active[PI_INDEX] = pThis->pDrv[0]->pfnIsActiveIn(pThis->pDrv[0],  pThis->voice_pi[0]) ? 1 : 0;
    1622     active[PO_INDEX] = pThis->pDrv[0]->pfnIsActiveOut(pThis->pDrv[0], pThis->voice_po[0]) ? 1 : 0;
    1623     active[MC_INDEX] = pThis->pDrv[0]->pfnIsActiveIn(pThis->pDrv[0],  pThis->voice_mc[0]) ? 1 : 0;
     1892
     1893#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1894    /* Writing only host backend values here and ignore data for other backends
     1895     * like VRDE and video recording. LUN 0 always is the host backend. */
     1896    if (pThis->cLUNs >= 1)
     1897    {
     1898        PPDMIAUDIOCONNECTOR pCon = pThis->paDrv[0]->pConnector;
     1899        AssertPtr(pCon);
     1900        active[PI_INDEX] = pCon->pfnIsActiveIn(pCon,  pThis->paDrv[0]->pStrmIn) ? 1 : 0;
     1901        active[PO_INDEX] = pCon->pfnIsActiveOut(pCon, pThis->paDrv[0]->pStrmOut) ? 1 : 0;
     1902        active[MC_INDEX] = pCon->pfnIsActiveIn(pCon,  pThis->paDrv[0]->pStrmMic) ? 1 : 0;
     1903    }
     1904    else
     1905        RT_ZERO(active);
    16241906#else
    16251907    active[PI_INDEX] = AUD_is_active_in( pThis->voice_pi) ? 1 : 0;
    16261908    active[PO_INDEX] = AUD_is_active_out(pThis->voice_po) ? 1 : 0;
    16271909    active[MC_INDEX] = AUD_is_active_in( pThis->voice_mc) ? 1 : 0;
    1628 #endif
     1910#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1911
    16291912    SSMR3PutMem(pSSM, active, sizeof(active));
    16301913
     
    16671950
    16681951#ifdef USE_MIXER
    1669     record_select(pThis, mixer_load(pThis, AC97_Record_Select));
    1670 # define V_(a, b) set_volume(pThis, a, b, mixer_load(pThis, a))
     1952    ichac97RecordSelect(pThis, ichac97MixerLoad(pThis, AC97_Record_Select));
     1953# define V_(a, b) ichac97SetVolume(pThis, a, b, ichac97MixerLoad(pThis, a))
     1954# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1955    V_(AC97_Master_Volume_Mute,  PDMAUDIOMIXERCTL_VOLUME);
     1956    V_(AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_PCM);
     1957    V_(AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN);
     1958# else
    16711959    V_(AC97_Master_Volume_Mute,  AUD_MIXER_VOLUME);
    16721960    V_(AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM);
    16731961    V_(AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN);
     1962# endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    16741963# undef V_
    16751964#endif /* USE_MIXER */
    1676     reset_voices(pThis, active);
     1965    ichac97ResetStreams(pThis, active);
    16771966
    16781967    pThis->bup_flag = 0;
     
    17021991 *          make sense to me so we'll do it.
    17031992 */
    1704 static DECLCALLBACK(void)  ac97Reset(PPDMDEVINS pDevIns)
     1993static DECLCALLBACK(void) ac97Reset(PPDMDEVINS pDevIns)
    17051994{
    17061995    PAC97STATE pThis = PDMINS_2_DATA(pDevIns, AC97STATE *);
     
    17091998     * Reset the device state (will need pDrv later).
    17101999     */
    1711     reset_bm_regs(pThis, &pThis->bm_regs[0]);
    1712     reset_bm_regs(pThis, &pThis->bm_regs[1]);
    1713     reset_bm_regs(pThis, &pThis->bm_regs[2]);
     2000    ichac97ResetBMRegs(pThis, &pThis->bm_regs[0]);
     2001    ichac97ResetBMRegs(pThis, &pThis->bm_regs[1]);
     2002    ichac97ResetBMRegs(pThis, &pThis->bm_regs[2]);
    17142003
    17152004    /*
     
    17182007     * the codec manually.
    17192008     */
    1720     mixer_reset(pThis);
    1721 }
     2009    ichac97MixerReset(pThis);
     2010}
     2011
     2012
     2013/**
     2014 * @interface_method_impl{PDMDEVREG,pfnDestruct}
     2015 */
     2016static DECLCALLBACK(int) ichac97Destruct(PPDMDEVINS pDevIns)
     2017{
     2018    PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE);
     2019
     2020    LogFlowFuncEnter();
     2021
     2022#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2023    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     2024    {
     2025        if (pThis->paDrv[lun])
     2026        {
     2027            RTMemFree(pThis->paDrv[lun]);
     2028            pThis->paDrv[lun] = NULL;
     2029        }
     2030    }
     2031
     2032    pThis->cLUNs = 0;
     2033
     2034    if (pThis->pMixer)
     2035    {
     2036        audioMixerDestroy(pThis->pMixer);
     2037        pThis->pMixer = NULL;
     2038    }
     2039#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     2040
     2041    return VINF_SUCCESS;
     2042}
     2043
     2044
     2045#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2046/**
     2047 * Attach command.
     2048 *
     2049 * This is called to let the device attach to a driver for a specified LUN
     2050 * during runtime. This is not called during VM construction, the device
     2051 * constructor have to attach to all the available drivers.
     2052 *
     2053 * @returns VBox status code.
     2054 * @param   pDevIns     The device instance.
     2055 * @param   uLUN        The logical unit which is being detached.
     2056 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
     2057 */
     2058static DECLCALLBACK(int) ichac97Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
     2059{
     2060    PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE);
     2061
     2062    AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
     2063                    ("AC'97 device does not support hotplugging\n"),
     2064                    VERR_INVALID_PARAMETER);
     2065
     2066    /*
     2067     * Attach driver.
     2068     */
     2069    char *pszDesc = NULL;
     2070    if (RTStrAPrintf(&pszDesc, "Audio driver port (AC'97) for LUN #%u", uLUN) <= 0)
     2071        AssertMsgReturn(pszDesc,
     2072                        ("Not enough memory for AC'97 driver port description of LUN #%u\n", uLUN),
     2073                        VERR_NO_MEMORY);
     2074
     2075    int rc = PDMDevHlpDriverAttach(pDevIns, uLUN,
     2076                                   &pThis->IBase, &pThis->pDrvBase, pszDesc);
     2077    if (RT_SUCCESS(rc))
     2078    {
     2079        PAC97DRIVER pDrv = (PAC97DRIVER)RTMemAllocZ(sizeof(AC97DRIVER));
     2080        if (pDrv)
     2081        {
     2082            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
     2083            AssertMsg(pDrv->pConnector != NULL,
     2084                      ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n",
     2085                      uLUN, rc));
     2086            pDrv->pAC97State = pThis;
     2087            pDrv->uLUN = uLUN;
     2088
     2089            LogFlowFunc(("LUN #%u is using connector %p\n", uLUN, pDrv->pConnector));
     2090
     2091            pThis->paDrv[uLUN] = pDrv;
     2092            pThis->cLUNs++;
     2093        }
     2094        else
     2095            rc = VERR_NO_MEMORY;
     2096    }
     2097    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     2098    {
     2099        LogFunc(("No attached driver for LUN #%u\n", uLUN));
     2100    }
     2101    else if (RT_FAILURE(rc))
     2102        AssertMsgFailed(("Failed to attach AC'97 LUN #%u (\"%s\"), rc=%Rrc\n",
     2103                        uLUN, pszDesc, rc));
     2104
     2105    RTStrFree(pszDesc);
     2106
     2107    LogFlowFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
     2108    return rc;
     2109}
     2110#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    17222111
    17232112
     
    17272116static DECLCALLBACK(int) ichac97Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
    17282117{
    1729     AC97STATE  *pThis = PDMINS_2_DATA(pDevIns, AC97STATE *);
    1730     int             rc;
     2118    PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE);
    17312119
    17322120    Assert(iInstance == 0);
     
    17702158     * saved state item.
    17712159     */
    1772     rc = PDMDevHlpPCIRegister(pDevIns, &pThis->PciDev);
     2160    int rc = PDMDevHlpPCIRegister(pDevIns, &pThis->PciDev);
    17732161    if (RT_FAILURE (rc))
    17742162        return rc;
     
    17902178     */
    17912179#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1792     for (uint32_t lun = 0; lun < 2; lun++)
    1793     {
    1794         rc = PDMDevHlpDriverAttach(pDevIns, lun, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port");
    1795         if (RT_SUCCESS(rc))
    1796         {
    1797             pThis->pDrv[lun] = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
    1798             AssertMsgReturn(pThis->pDrv[lun],
    1799                             ("Configuration error: instance %d has no host audio interface!\n", iInstance),
    1800                             VERR_PDM_MISSING_INTERFACE);
    1801         }
    1802         else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    1803             Log(("ac97: No attached driver!\n"));
    1804         else if (RT_FAILURE(rc))
    1805         {
    1806             AssertMsgFailed(("Failed to attach AC97 LUN #%d! rc=%Rrc\n", lun, rc));
    1807             return rc;
    1808         }
    1809     }
     2180    /* We support 32 LUNs max. This should be enough for now. */
     2181    for (uint8_t lun = 0; lun < 32 ; lun++)
     2182    {
     2183        LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", lun));
     2184        rc = ichac97Attach(pDevIns, lun, PDM_TACH_FLAGS_NOT_HOT_PLUG);
     2185        if (RT_FAILURE(rc))
     2186        {
     2187            if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     2188                rc = VINF_SUCCESS;
     2189            break;
     2190        }
     2191    }
     2192
     2193    LogRel(("AC97: %RU8 LUN(s) attached\n", pThis->cLUNs));
    18102194#else
    18112195    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port");
     
    18172201        return rc;
    18182202    }
    1819 #endif
    1820 
    1821 
    1822 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1823     pThis->pDrv[0]->pfnRegisterCard(pThis->pDrv[0], "ICH0" );
    1824 #else
     2203#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     2204
     2205#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    18252206    AUD_register_card("ICH0", &pThis->card);
    18262207#endif
     
    18282209
    18292210#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1830     for (uint32_t lun =0; lun < 2; lun++)
    1831     {
    1832         if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun]))
    1833             LogRel(("AC97: WARNING: Unable to open PCM IN!\n"));
    1834         if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))
    1835             LogRel(("AC97: WARNING: Unable to open PCM MC!\n"));
    1836         if (!pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun]))
    1837             LogRel(("AC97: WARNING: Unable to open PCM OUT!\n"));
     2211    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     2212    {
     2213        if (!pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn))
     2214            LogRel(("AC97: WARNING: Unable to open PCM line input for LUN #%RU32!\n", lun));
     2215        if (!pThis->paDrv[lun]->pConnector->pfnIsOutputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmOut))
     2216            LogRel(("AC97: WARNING: Unable to open PCM output for LUN #%RU32!\n", lun));
     2217        if (!pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic))
     2218            LogRel(("AC97: WARNING: Unable to open PCM microphone input for LUN #%RU32!\n", lun));
     2219    }
     2220
     2221    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     2222    {
     2223        if (   !pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn)
     2224            && !pThis->paDrv[lun]->pConnector->pfnIsOutputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmOut)
     2225            && !pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic))
     2226        {
     2227            /* Was not able initialize *any* stream. Select the NULL audio driver instead. */
     2228            pThis->paDrv[lun]->pConnector->pfnCloseIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn);
     2229            pThis->paDrv[lun]->pConnector->pfnCloseOut(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmOut);
     2230            pThis->paDrv[lun]->pConnector->pfnCloseIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic);
     2231
     2232            pThis->paDrv[lun]->pStrmOut = NULL;
     2233            pThis->paDrv[lun]->pStrmIn = NULL;
     2234            pThis->paDrv[lun]->pStrmMic = NULL;
     2235
     2236            pThis->paDrv[lun]->pConnector->pfnInitNull(pThis->paDrv[lun]->pConnector);
     2237            ac97Reset(pDevIns);
     2238
     2239            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     2240                N_("No audio devices could be opened. Selecting the NULL audio backend "
     2241                   "with the consequence that no sound is audible"));
     2242        }
     2243        else if (   !pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn)
     2244                 || !pThis->paDrv[lun]->pConnector->pfnIsOutputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmOut)
     2245                 || !pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic))
     2246        {
     2247            char   szMissingStreams[128];
     2248            size_t len = 0;
     2249            if (!pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn))
     2250                len = RTStrPrintf(szMissingStreams, sizeof(szMissingStreams), "PCM Input");
     2251            if (!pThis->paDrv[lun]->pConnector->pfnIsOutputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmOut))
     2252                len += RTStrPrintf(szMissingStreams + len, sizeof(szMissingStreams) - len, len ? ", PCM Output" : "PCM Output");
     2253            if (!pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic))
     2254                len += RTStrPrintf(szMissingStreams + len, sizeof(szMissingStreams) - len, len ? ", PCM Mic" : "PCM Mic");
     2255
     2256            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     2257                N_("Some AC'97 audio streams (%s) could not be opened. Guest applications generating audio "
     2258                "output or depending on audio input may hang. Make sure your host audio device "
     2259                "is working properly. Check the logfile for error messages of the audio "
     2260                "subsystem"), szMissingStreams);
     2261        }
    18382262    }
    18392263#else
     
    18452269        LogRel(("AC97: WARNING: Unable to open PCM OUT!\n"));
    18462270
    1847 #endif
    1848 
    1849 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1850     for (uint32_t lun = 0; lun < 2; lun++)
    1851     {
    1852         if (   !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun])
    1853             && !pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun])
    1854             && !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))
    1855         {
    1856         /* Was not able initialize *any* voice. Select the NULL audio driver instead */
    1857             pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_pi[lun]);
    1858             pThis->pDrv[lun]->pfnCloseOut(pThis->pDrv[lun], pThis->voice_po[lun]);
    1859             pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_mc[lun]);
    1860 
    1861             pThis->voice_po[lun] = NULL;
    1862             pThis->voice_pi[lun] = NULL;
    1863             pThis->voice_mc[lun] = NULL;
    1864 
    1865             pThis->pDrv[lun]->pfnInitNull(pThis->pDrv[lun]);
    1866             ac97Reset(pDevIns);
    1867 
    1868             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    1869                 N_("No audio devices could be opened. Selecting the NULL audio backend "
    1870                    "with the consequence that no sound is audible"));
    1871         }
    1872         else if (   !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun])
    1873                  || !pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun])
    1874                  || !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))
    1875         {
    1876             char   szMissingVoices[128];
    1877             size_t len = 0;
    1878             if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun]))
    1879                 len = RTStrPrintf(szMissingVoices, sizeof(szMissingVoices), "PCM_in");
    1880             if (!pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun]))
    1881                 len += RTStrPrintf(szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out");
    1882             if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))
    1883                 len += RTStrPrintf(szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_mic" : "PCM_mic");
    1884 
    1885             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    1886                 N_("Some audio devices (%s) could not be opened. Guest applications generating audio "
    1887                 "output or depending on audio input may hang. Make sure your host audio device "
    1888                 "is working properly. Check the logfile for error messages of the audio "
    1889                 "subsystem"), szMissingVoices);
    1890         }
    1891     }
    1892 #else
    18932271    if (   !AUD_is_host_voice_in_ok( pThis->voice_pi)
    18942272        && !AUD_is_host_voice_out_ok(pThis->voice_po)
     
    19282306               "subsystem"), szMissingVoices);
    19292307    }
    1930 #endif
     2308#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     2309
    19312310    return VINF_SUCCESS;
    19322311}
     
    19582337    ichac97Construct,
    19592338    /* pfnDestruct */
    1960     NULL,
     2339    ichac97Destruct,
    19612340    /* pfnRelocate */
    19622341    NULL,
  • trunk/src/VBox/Devices/Audio/DevIchHda.cpp

    r53416 r53442  
    99
    1010/*
    11  * Copyright (C) 2006-2013 Oracle Corporation
     11 * Copyright (C) 2006-2014 Oracle Corporation
    1212 *
    1313 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2323*   Header Files                                                               *
    2424*******************************************************************************/
    25 #define LOG_GROUP LOG_GROUP_DEV_AUDIO
    2625#include <VBox/vmm/pdmdev.h>
    27 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2826#include <VBox/vmm/pdmaudioifs.h>
    29 #endif
    3027#include <VBox/version.h>
    3128
     
    3835# include <iprt/mem.h>
    3936#endif
     37#include <iprt/list.h>
     38
     39#if 0
     40/* Warning: Enabling this causes a *lot* of output! */
     41#ifdef LOG_GROUP
     42# undef LOG_GROUP
     43#endif
     44#define LOG_GROUP LOG_GROUP_DEV_AUDIO
     45#include <VBox/log.h>
     46#endif
    4047
    4148#include "VBoxDD.h"
    4249
    43 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    44 extern "C" {
    45 #include "audio.h"
    46 }
     50#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     51# include "AudioMixer.h"
     52#else
     53 extern "C" {
     54  #include "audio.h"
     55 }
    4756#endif
    4857#include "DevIchHdaCodec.h"
    49 
    5058
    5159/*******************************************************************************
     
    279287#define HDA_STREAM_REG_DEF(name, num)           (HDA_REG_SD##num##name)
    280288#define HDA_STREAM_RMX_DEF(name, num)           (HDA_RMX_SD##num##name)
    281 /* Note: sdnum here _MUST_ be stream reg number [0,7] */
    282 #define HDA_STREAM_REG(pThis, name, sdnum)     (HDA_REG_IND((pThis), HDA_REG_SD0##name + (sdnum) * 10))
     289/* Note: sdnum here _MUST_ be stream reg number [0,7]. */
     290#define HDA_STREAM_REG(pThis, name, sdnum)      (HDA_REG_IND((pThis), HDA_REG_SD0##name + (sdnum) * 10))
    283291
    284292#define HDA_REG_SD0CTL              34 /* 0x80 */
     
    508516#define HDA_RMX_SD7BDPU             (HDA_STREAM_RMX_DEF(BDPU, 0) + 70)
    509517
     518#define HDA_CODEC_CAD_SHIFT         28
     519/* Encodes the (required) LUN into a codec command. */
     520#define HDA_CODEC_CMD(cmd, lun)     ((cmd) | (lun << HDA_CODEC_CAD_SHIFT))
     521
     522
    510523
    511524/*******************************************************************************
     
    535548} HDASTREAMTRANSFERDESC, *PHDASTREAMTRANSFERDESC;
    536549
     550#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     551/**
     552 * Struct for maintaining a host backend driver.
     553 * This driver must be associated to one, and only one,
     554 * HDA codec. The HDA controller does the actual multiplexing
     555 * of HDA codec data to various host backend drivers then.
     556 */
     557typedef struct HDADRIVER
     558{
     559    RTLISTNODE                         Node;
     560    /** Pointer to HDA controller (state). */
     561    PHDASTATE                          pHDAState;
     562    /** LUN to which this driver has been assigned. */
     563    uint8_t                            uLUN;
     564    /** Audio connector interface to the underlying
     565     *  host backend. */
     566    R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pConnector;
     567    /** PCM line input stream. */
     568    R3PTRTYPE(PPDMAUDIOGSTSTRMIN)      pStrmIn;
     569    /** Mixer handle for line input stream. */
     570    R3PTRTYPE(PAUDMIXSTREAM)           phStrmIn;
     571    /** PCM microphone input stream. */
     572    R3PTRTYPE(PPDMAUDIOGSTSTRMIN)      pStrmMic;
     573    /** Mixer handle for microphone input stream. */
     574    R3PTRTYPE(PAUDMIXSTREAM)           phStrmMic;
     575    /** PCM output stream. */
     576    R3PTRTYPE(PPDMAUDIOGSTSTRMOUT)     pGstStrmOut;
     577} HDADRIVER, *PHDADRIVER;
     578#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     579
    537580/**
    538581 * ICH Intel HD Audio Controller state.
     
    551594    uint32_t                           u32Padding;
    552595
    553     /** Pointer to the connector of the attached audio driver. */
    554 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    555     R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pDrv[2];
    556 #else
    557     R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pDrv;
    558 #endif
    559596    /** Pointer to the attached audio driver. */
    560597    R3PTRTYPE(PPDMIBASE)               pDrvBase;
     
    569606    uint64_t                           u64RIRBBase;
    570607    uint64_t                           u64DPBase;
    571     /** pointer to CORB buf */
     608    /** Pointer to CORB buffer. */
    572609    R3PTRTYPE(uint32_t *)              pu32CorbBuf;
    573     /** size in bytes of CORB buf */
     610    /** Size in bytes of CORB buffer. */
    574611    uint32_t                           cbCorbBuf;
    575612    uint32_t                           u32Padding2;
    576     /** pointer on RIRB buf */
     613    /** Pointer to RIRB buffer. */
    577614    R3PTRTYPE(uint64_t *)              pu64RirbBuf;
    578     /** size in bytes of RIRB buf */
     615    /** Size in bytes of RIRB buffer. */
    579616    uint32_t                           cbRirbBuf;
    580     /** indicates if HDA in reset. */
     617    /** Indicates if HDA is in reset. */
    581618    bool                               fInReset;
    582619    /** Interrupt on completion */
     
    587624    bool                               fRCEnabled;
    588625#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    589     /** The HDA codec state. */
    590     R3PTRTYPE(PHDACODEC)               pCodec[2];
     626    /** Number of active + allocated LUNs. Each
     627     *  LUN has a HDA driver assigned. */
     628    uint8_t                            cLUNs;
     629    /** The HDA codec to use. */
     630    R3PTRTYPE(PHDACODEC)               pCodec;
     631    /** Array of active HDA drivers. */
     632    R3PTRTYPE(PHDADRIVER)              paDrv[32];
     633    /** The device' software mixer. */
     634    R3PTRTYPE(PAUDIOMIXER)             pMixer;
     635    /** Audio sink for line input. */
     636    R3PTRTYPE(PAUDMIXSINK)             pSinkLineIn;
     637    /** Audio sink for microphone input. */
     638    R3PTRTYPE(PAUDMIXSINK)             pSinkMicIn;
    591639#else
     640    R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pDrv;
     641    /** The HDA codec to use. */
    592642    R3PTRTYPE(PHDACODEC)               pCodec;
    593 #endif
     643#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    594644    uint64_t                           u64BaseTS;
    595645    /** 1.2.3.4.5.6.7. - someone please tell me what I'm counting! - .8.9.10... */
     
    646696static int hdaRegReadU8(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    647697static int hdaRegWriteU8(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     698
     699#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     700static void hdaTransfer(PHDADRIVER pDrv, ENMSOUNDSOURCE enmSrc, uint32_t cbAvail);
     701#else
     702static void hdaTransfer(PHDACODEC pCodec, ENMSOUNDSOURCE enmSource, int cbAvail);
     703#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    648704
    649705#ifdef IN_RING3
     
    774830    { 0x000FC, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteSDBDPU     , IA(SD3BDPU)   }, /* ISD3 Buffer Descriptor List Pointer-Upper Base Address */
    775831
    776     { 0x00100, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD4CTL)    }, /* Output Stream Descriptor 0 (OSD0) Control */
    777     { 0x00103, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD4STS)    }, /* OSD0 Status */
    778     { 0x00104, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD4LPIB)   }, /* OSD0 Link Position In Buffer */
    779     { 0x00108, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , OA(SD4CBL)    }, /* OSD0 Cyclic Buffer Length */
    780     { 0x0010C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD4LVI)    }, /* OSD0 Last Valid Index */
    781     { 0x0010E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD4FIFOW)  }, /* OSD0 FIFO Watermark */
    782     { 0x00110, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS    , OA(SD4FIFOS)  }, /* OSD0 FIFO Size */
    783     { 0x00112, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteSDFMT      , OA(SD4FMT)    }, /* OSD0 Format */
    784     { 0x00118, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32          , hdaRegWriteSDBDPL     , OA(SD4BDPL)   }, /* OSD0 Buffer Descriptor List Pointer-Lower Base Address */
    785     { 0x0011C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteSDBDPU     , OA(SD4BDPU)   }, /* OSD0 Buffer Descriptor List Pointer-Upper Base Address */
    786 
    787     { 0x00120, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD5CTL)    }, /* Output Stream Descriptor 0 (OSD1) Control */
    788     { 0x00123, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD5STS)    }, /* OSD1 Status */
    789     { 0x00124, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD5LPIB)   }, /* OSD1 Link Position In Buffer */
    790     { 0x00128, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , OA(SD5CBL)    }, /* OSD1 Cyclic Buffer Length */
    791     { 0x0012C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD5LVI)    }, /* OSD1 Last Valid Index */
    792     { 0x0012E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD5FIFOW)  }, /* OSD1 FIFO Watermark */
    793     { 0x00130, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS    , OA(SD5FIFOS)  }, /* OSD1 FIFO Size */
    794     { 0x00132, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteSDFMT      , OA(SD5FMT)    }, /* OSD1 Format */
    795     { 0x00138, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32          , hdaRegWriteSDBDPL     , OA(SD5BDPL)   }, /* OSD1 Buffer Descriptor List Pointer-Lower Base Address */
    796     { 0x0013C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteSDBDPU     , OA(SD5BDPU)   }, /* OSD1 Buffer Descriptor List Pointer-Upper Base Address */
    797 
    798     { 0x00140, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD6CTL)    }, /* Output Stream Descriptor 0 (OSD2) Control */
    799     { 0x00143, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD6STS)    }, /* OSD2 Status */
    800     { 0x00144, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD6LPIB)   }, /* OSD2 Link Position In Buffer */
    801     { 0x00148, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , OA(SD6CBL)    }, /* OSD2 Cyclic Buffer Length */
    802     { 0x0014C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD6LVI)    }, /* OSD2 Last Valid Index */
    803     { 0x0014E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD6FIFOW)  }, /* OSD2 FIFO Watermark */
    804     { 0x00150, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS    , OA(SD6FIFOS)  }, /* OSD2 FIFO Size */
    805     { 0x00152, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteSDFMT      , OA(SD6FMT)    }, /* OSD2 Format */
    806     { 0x00158, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32          , hdaRegWriteSDBDPL     , OA(SD6BDPL)   }, /* OSD2 Buffer Descriptor List Pointer-Lower Base Address */
    807     { 0x0015C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteSDBDPU     , OA(SD6BDPU)   }, /* OSD2 Buffer Descriptor List Pointer-Upper Base Address */
    808 
    809     { 0x00160, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD7CTL)    }, /* Output Stream Descriptor 0 (OSD3) Control */
    810     { 0x00163, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD7STS)    }, /* OSD3 Status */
    811     { 0x00164, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD7LPIB)   }, /* OSD3 Link Position In Buffer */
    812     { 0x00168, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , OA(SD7CBL)    }, /* OSD3 Cyclic Buffer Length */
    813     { 0x0016C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD7LVI)    }, /* OSD3 Last Valid Index */
    814     { 0x0016E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD7FIFOW)  }, /* OSD3 FIFO Watermark */
    815     { 0x00170, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS    , OA(SD7FIFOS)  }, /* OSD3 FIFO Size */
    816     { 0x00172, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteSDFMT      , OA(SD7FMT)    }, /* OSD3 Format */
    817     { 0x00178, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32          , hdaRegWriteSDBDPL     , OA(SD7BDPL)   }, /* OSD3 Buffer Descriptor List Pointer-Lower Base Address */
    818     { 0x0017C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteSDBDPU     , OA(SD7BDPU)   }, /* OSD3 Buffer Descriptor List Pointer-Upper Base Address */
     832    { 0x00100, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD4CTL)    }, /* Output Stream Descriptor 4 (OSD4) Control */
     833    { 0x00103, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD4STS)    }, /* OSD4 Status */
     834    { 0x00104, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD4LPIB)   }, /* OSD4 Link Position In Buffer */
     835    { 0x00108, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , OA(SD4CBL)    }, /* OSD4 Cyclic Buffer Length */
     836    { 0x0010C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD4LVI)    }, /* OSD4 Last Valid Index */
     837    { 0x0010E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD4FIFOW)  }, /* OSD4 FIFO Watermark */
     838    { 0x00110, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS    , OA(SD4FIFOS)  }, /* OSD4 FIFO Size */
     839    { 0x00112, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteSDFMT      , OA(SD4FMT)    }, /* OSD4 Format */
     840    { 0x00118, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32          , hdaRegWriteSDBDPL     , OA(SD4BDPL)   }, /* OSD4 Buffer Descriptor List Pointer-Lower Base Address */
     841    { 0x0011C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteSDBDPU     , OA(SD4BDPU)   }, /* OSD4 Buffer Descriptor List Pointer-Upper Base Address */
     842
     843    { 0x00120, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD5CTL)    }, /* Output Stream Descriptor 5 (OSD5) Control */
     844    { 0x00123, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD5STS)    }, /* OSD5 Status */
     845    { 0x00124, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD5LPIB)   }, /* OSD5 Link Position In Buffer */
     846    { 0x00128, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , OA(SD5CBL)    }, /* OSD5 Cyclic Buffer Length */
     847    { 0x0012C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD5LVI)    }, /* OSD5 Last Valid Index */
     848    { 0x0012E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD5FIFOW)  }, /* OSD5 FIFO Watermark */
     849    { 0x00130, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS    , OA(SD5FIFOS)  }, /* OSD5 FIFO Size */
     850    { 0x00132, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteSDFMT      , OA(SD5FMT)    }, /* OSD5 Format */
     851    { 0x00138, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32          , hdaRegWriteSDBDPL     , OA(SD5BDPL)   }, /* OSD5 Buffer Descriptor List Pointer-Lower Base Address */
     852    { 0x0013C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteSDBDPU     , OA(SD5BDPU)   }, /* OSD5 Buffer Descriptor List Pointer-Upper Base Address */
     853
     854    { 0x00140, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD6CTL)    }, /* Output Stream Descriptor 6 (OSD6) Control */
     855    { 0x00143, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD6STS)    }, /* OSD6 Status */
     856    { 0x00144, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD6LPIB)   }, /* OSD6 Link Position In Buffer */
     857    { 0x00148, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , OA(SD6CBL)    }, /* OSD6 Cyclic Buffer Length */
     858    { 0x0014C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD6LVI)    }, /* OSD6 Last Valid Index */
     859    { 0x0014E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD6FIFOW)  }, /* OSD6 FIFO Watermark */
     860    { 0x00150, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS    , OA(SD6FIFOS)  }, /* OSD6 FIFO Size */
     861    { 0x00152, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteSDFMT      , OA(SD6FMT)    }, /* OSD6 Format */
     862    { 0x00158, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32          , hdaRegWriteSDBDPL     , OA(SD6BDPL)   }, /* OSD6 Buffer Descriptor List Pointer-Lower Base Address */
     863    { 0x0015C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteSDBDPU     , OA(SD6BDPU)   }, /* OSD6 Buffer Descriptor List Pointer-Upper Base Address */
     864
     865    { 0x00160, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD7CTL)    }, /* Output Stream Descriptor 7 (OSD7) Control */
     866    { 0x00163, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD7STS)    }, /* OSD7 Status */
     867    { 0x00164, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD7LPIB)   }, /* OSD7 Link Position In Buffer */
     868    { 0x00168, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , OA(SD7CBL)    }, /* OSD7 Cyclic Buffer Length */
     869    { 0x0016C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD7LVI)    }, /* OSD7 Last Valid Index */
     870    { 0x0016E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD7FIFOW)  }, /* OSD7 FIFO Watermark */
     871    { 0x00170, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16          , hdaRegWriteSDFIFOS    , OA(SD7FIFOS)  }, /* OSD7 FIFO Size */
     872    { 0x00172, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16          , hdaRegWriteSDFMT      , OA(SD7FMT)    }, /* OSD7 Format */
     873    { 0x00178, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32          , hdaRegWriteSDBDPL     , OA(SD7BDPL)   }, /* OSD7 Buffer Descriptor List Pointer-Lower Base Address */
     874    { 0x0017C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteSDBDPU     , OA(SD7BDPU)   }, /* OSD7 Buffer Descriptor List Pointer-Upper Base Address */
    819875};
    820876
     
    899955        case HDA_SDFIFOW_32B: return 32;
    900956        default:
    901             AssertMsgFailed(("hda: unsupported value (%x) in SDFIFOW(,%d)\n", HDA_REG_IND(pThis, pStreamDesc->u8Strm), pStreamDesc->u8Strm));
     957            AssertMsgFailed(("unsupported value (%x) in SDFIFOW(,%d)\n", HDA_REG_IND(pThis, pStreamDesc->u8Strm), pStreamDesc->u8Strm));
    902958    }
    903959#endif
     
    923979    if (HDA_REG_FLAG_VALUE(pThis, INTCTL, GIE))
    924980    {
    925         Log(("hda: irq %s\n", fIrq ? "asserted" : "deasserted"));
     981        LogFunc(("irq %s\n", fIrq ? "asserted" : "deasserted"));
    926982        PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , fIrq);
    927983    }
     
    10501106        do
    10511107        {
    1052             Log(("hda: corb%02x: ", i));
     1108            LogFunc(("corb%02x: ", i));
    10531109            uint8_t j = 0;
    10541110            do
     
    10611117                else
    10621118                    prefix = "   "; /* three spaces */
    1063                 Log(("%s%08x", prefix, pThis->pu32CorbBuf[i + j]));
     1119                LogFunc(("%s%08x", prefix, pThis->pu32CorbBuf[i + j]));
    10641120                j++;
    10651121            } while (j < 8);
    1066             Log(("\n"));
     1122            LogFunc(("\n"));
    10671123            i += 8;
    10681124        } while(i != 0);
     
    10781134        uint8_t i = 0;
    10791135        do {
    1080             Log(("hda: rirb%02x: ", i));
     1136            LogFunc(("rirb%02x: ", i));
    10811137            uint8_t j = 0;
    10821138            do {
     
    10861142                else
    10871143                    prefix = "   ";
    1088                 Log((" %s%016lx", prefix, pThis->pu64RirbBuf[i + j]));
     1144                LogFunc((" %s%016lx", prefix, pThis->pu64RirbBuf[i + j]));
    10891145            } while (++j < 8);
    1090             Log(("\n"));
     1146            LogFunc(("\n"));
    10911147            i += 8;
    10921148        } while (i != 0);
     
    11121168    rirbWp = HDA_REG(pThis, RIRBWP);
    11131169    Assert((corbWp != corbRp));
    1114     Log(("hda: CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP),
    1115          HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));
     1170    LogFlowFunc(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP),
     1171                 HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));
    11161172    while (corbRp != corbWp)
    11171173    {
     
    11211177        corbRp++;
    11221178        cmd = pThis->pu32CorbBuf[corbRp];
    1123 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1124         for (uint32_t lun = 0; lun < 1; lun++)
    1125             rc = pThis->pCodec[lun]->pfnLookup(pThis->pCodec[lun], cmd, &pfn);
    1126 #else
    1127         rc = pThis->pCodec->pfnLookup(pThis->pCodec, cmd, &pfn);
    1128 #endif
     1179
     1180        rc = pThis->pCodec->pfnLookup(pThis->pCodec,
     1181                                      HDA_CODEC_CMD(cmd, 0 /* Codec index */),
     1182                                      &pfn);
     1183        if (RT_SUCCESS(rc))
     1184        {
     1185            rc = pfn(pThis->pCodec,
     1186                     HDA_CODEC_CMD(cmd, 0 /* LUN */), &resp);
     1187        }
     1188
    11291189        if (RT_FAILURE(rc))
    11301190            AssertRCReturn(rc, rc);
     
    11321192        (rirbWp)++;
    11331193
    1134         if (RT_LIKELY(pfn))
    1135 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1136         {
    1137             for (uint32_t lun = 0; lun < 1; lun++)
    1138                 rc = pfn(pThis->pCodec[lun], cmd, &resp);
    1139         }
    1140 #else
    1141             rc = pfn(pThis->pCodec, cmd, &resp);
    1142 #endif
    1143         else
    1144             rc = VERR_INVALID_FUNCTION;
    1145 
    1146         if (RT_FAILURE(rc))
    1147             AssertRCReturn(rc, rc);
    1148         Log(("hda: verb:%08x->%016lx\n", cmd, resp));
     1194        LogFunc(("verb:%08x->%016lx\n", cmd, resp));
    11491195        if (   (resp & CODEC_RESPONSE_UNSOLICITED)
    11501196            && !HDA_REG_FLAG_VALUE(pThis, GCTL, UR))
    11511197        {
    1152             Log(("hda: unexpected unsolicited response.\n"));
     1198            LogFunc(("unexpected unsolicited response.\n"));
    11531199            HDA_REG(pThis, CORBRP) = corbRp;
    11541200            return rc;
     
    11621208    HDA_REG(pThis, RIRBWP) = rirbWp;
    11631209    rc = hdaCmdSync(pThis, false);
    1164     Log(("hda: CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP),
     1210    LogFunc(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP),
    11651211         HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));
    11661212    if (HDA_REG_FLAG_VALUE(pThis, RIRBCTL, RIC))
     
    11781224static void hdaStreamReset(PHDASTATE pThis, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc, uint8_t u8Strm)
    11791225{
    1180     Log(("hda: reset of stream (%d) started\n", u8Strm));
     1226    LogFunc(("reset of stream (%d) started\n", u8Strm));
    11811227    Assert((   pThis
    11821228            && pBdle
    11831229            && pStreamDesc
    11841230            && u8Strm <= 7));
    1185     memset(pBdle, 0, sizeof(HDABDLEDESC));
     1231    RT_BZERO(pBdle, sizeof(HDABDLEDESC));
    11861232    *pStreamDesc->pu32Lpib = 0;
    11871233    *pStreamDesc->pu32Sts = 0;
     
    11981244    HDA_STREAM_REG(pThis, BDPU, u8Strm) = 0;
    11991245    HDA_STREAM_REG(pThis, BDPL, u8Strm) = 0;
    1200     Log(("hda: reset of stream (%d) finished\n", u8Strm));
     1246    LogFunc(("reset of stream (%d) finished\n", u8Strm));
    12011247}
    12021248
     
    12861332            || HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA))
    12871333        {
    1288             Log(("hda: HDA enters in reset with DMA(RIRB:%s, CORB:%s)\n",
     1334            LogFunc(("HDA enters in reset with DMA(RIRB:%s, CORB:%s)\n",
    12891335                HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) ? "on" : "off",
    12901336                HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA) ? "on" : "off"));
     
    14141460         */
    14151461        Assert((!fReset));
    1416         Log(("hda: guest initiated exit of stream reset.\n"));
     1462        LogFunc(("guest initiated exit of stream reset.\n"));
    14171463    }
    14181464    else if (fReset)
     
    14321478                pBdle = &pThis->StInBdle;
    14331479                break;
     1480            case HDA_REG_SD2CTL:
     1481                u8Strm = 2;
     1482                pBdle = &pThis->StMicBdle;
     1483                break;
    14341484            case HDA_REG_SD4CTL:
    14351485                u8Strm = 4;
     
    14371487                break;
    14381488            default:
    1439                 Log(("hda: changing SRST bit on non-attached stream\n"));
     1489                LogFunc(("changing SRST bit on non-attached stream\n"));
    14401490                return hdaRegWriteU24(pThis, iReg, u32Value);
    14411491        }
    1442         Log(("hda: guest initiated enter to stream reset.\n"));
     1492        LogFunc(("guest initiated enter to stream reset.\n"));
    14431493        hdaInitTransferDescriptor(pThis, pBdle, u8Strm, &StreamDesc);
    14441494        hdaStreamReset(pThis, pBdle, &StreamDesc, u8Strm);
     
    14581508            {
    14591509                case HDA_REG_SD0CTL:
    1460  #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1461                     for (uint32_t lun = 0; lun < 1; lun++)
    1462                         pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceIn, fRun);
    1463  #else
     1510#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1511                    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     1512                        pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector,
     1513                                                                   pThis->paDrv[lun]->pStrmIn, fRun);
     1514#else
    14641515                    AUD_set_active_in(pThis->pCodec->SwVoiceIn, fRun);
    1465  #endif
     1516#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1517                    break;
     1518#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1519                case HDA_REG_SD2CTL:
     1520                    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     1521                        pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector,
     1522                                                                   pThis->paDrv[lun]->pStrmMic, fRun);
     1523#else
     1524
     1525#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    14661526                    break;
    14671527                case HDA_REG_SD4CTL:
    1468  #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1469                     for (uint32_t lun = 0; lun < 1; lun++)
    1470                         pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, fRun);
    1471  #else
     1528#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1529                    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     1530                        pThis->paDrv[lun]->pConnector->pfnEnableOut(pThis->paDrv[lun]->pConnector,
     1531                                                                    pThis->paDrv[lun]->pGstStrmOut, fRun);
     1532#else
    14721533                    AUD_set_active_out(pThis->pCodec->SwVoiceOut, fRun);
    1473  #endif
     1534#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    14741535                    break;
    14751536                default:
    1476                     Log(("hda: changing RUN bit on non-attached stream\n"));
     1537                    AssertMsgFailed(("Changing RUN bit on non-attached stream, register %RU32\n", iReg));
    14771538                    break;
    14781539            }
    14791540        }
    1480 #else
     1541#else /* !IN_RING3 */
    14811542        return VINF_IOM_R3_MMIO_WRITE;
    14821543#endif
     
    15121573            return hdaRegWriteU16(pThis, iReg, u32Value);
    15131574        default:
    1514             Log(("hda: Attempt to store unsupported value(%x) in SDFIFOW\n", u32Value));
     1575            LogFunc(("Attempt to store unsupported value(%x) in SDFIFOW\n", u32Value));
    15151576            return hdaRegWriteU16(pThis, iReg, HDA_SDFIFOW_32B);
    15161577    }
     
    15311592        case HDA_REG_SD2FIFOS:
    15321593        case HDA_REG_SD3FIFOS:
    1533             Log(("hda: Guest tries change value of FIFO size of Input Stream\n"));
    1534             return VINF_SUCCESS;
     1594            LogFunc(("Guest tries change value of FIFO size of input stream\n"));
     1595            break;
    15351596        case HDA_REG_SD4FIFOS:
    15361597        case HDA_REG_SD5FIFOS:
     
    15471608
    15481609                case HDA_SDONFIFO_256B:
    1549                     Log(("hda: 256-bit is unsupported, HDA is switched into 192-bit mode\n"));
     1610                    LogFunc(("256-bit is unsupported, HDA is switched into 192-bit mode\n"));
    15501611                default:
    15511612                    return hdaRegWriteU16(pThis, iReg, HDA_SDONFIFO_192B);
    15521613            }
    1553             return VINF_SUCCESS;
     1614            break;
    15541615        default:
    1555             AssertMsgFailed(("Something weird happened with register lookup routine"));
    1556     }
     1616            AssertMsgFailed(("Something weird happened with register lookup routine\n"));
     1617    }
     1618
    15571619    return VINF_SUCCESS;
    15581620}
    15591621
    15601622#ifdef IN_RING3
    1561 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1562 static void hdaSdFmtToAudSettings(uint32_t u32SdFmt, uint32_t * pFrequency, uint32_t * pChannels, audfmt_e *pFormat, uint32_t *pEndian)
    1563 # else
    1564 static void hdaSdFmtToAudSettings(uint32_t u32SdFmt, audsettings_t *pAudSetting)
    1565 # endif
    1566 {
    1567 # ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    1568     Assert((pAudSetting));
    1569 # endif
     1623#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1624static int hdaSdFmtToAudSettings(uint32_t u32SdFmt, PPDMAUDIOSTREAMCFG pCfg)
     1625#else
     1626static int hdaSdFmtToAudSettings(uint32_t u32SdFmt, audsettings_t *pCfg)
     1627#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1628{
     1629    AssertPtrReturn(pCfg, VERR_INVALID_POINTER);
     1630
    15701631# define EXTRACT_VALUE(v, mask, shift) ((v & ((mask) << (shift))) >> (shift))
     1632
     1633    int rc = VINF_SUCCESS;
     1634
    15711635    uint32_t u32Hz = (u32SdFmt & HDA_SDFMT_BASE_RATE_SHIFT) ? 44100 : 48000;
    15721636    uint32_t u32HzMult = 1;
    15731637    uint32_t u32HzDiv = 1;
     1638
    15741639    switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_MULT_MASK, HDA_SDFMT_MULT_SHIFT))
    15751640    {
     
    15791644        case 3: u32HzMult = 4; break;
    15801645        default:
    1581             Log(("hda: unsupported multiplier %x\n", u32SdFmt));
     1646            LogFunc(("Unsupported multiplier %x\n",
     1647                     EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_MULT_MASK, HDA_SDFMT_MULT_SHIFT)));
     1648            rc = VERR_NOT_SUPPORTED;
     1649            break;
    15821650    }
    15831651    switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_DIV_MASK, HDA_SDFMT_DIV_SHIFT))
     
    15911659        case 6: u32HzDiv = 7; break;
    15921660        case 7: u32HzDiv = 8; break;
    1593     }
    1594 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1595     *pFrequency = u32Hz * u32HzMult / u32HzDiv;
    1596 # else
    1597     pAudSetting->freq = u32Hz * u32HzMult / u32HzDiv;
    1598 # endif
     1661        default:
     1662            LogFunc(("Unsupported divisor %x\n",
     1663                     EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_DIV_MASK, HDA_SDFMT_DIV_SHIFT)));
     1664            rc = VERR_NOT_SUPPORTED;
     1665            break;
     1666    }
     1667
     1668#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1669    PDMAUDIOFMT enmFmt = AUD_FMT_S16; /* Default to 16-bit signed. */
     1670#else
     1671    audfmt_e enmFmt = AUD_FMT_S16; /* Default to 16-bit signed. */
     1672#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    15991673
    16001674    switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))
    16011675    {
    16021676        case 0:
    1603             Log(("hda: %s requested 8-bit\n", __FUNCTION__));
    1604 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1605             *pFormat = AUD_FMT_S8;
    1606 # else
    1607             pAudSetting->fmt = AUD_FMT_S8;
    1608 # endif
     1677            LogFunc(("%s requested 8-bit\n", __FUNCTION__));
     1678#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1679            enmFmt = AUD_FMT_S8;
     1680#else
     1681            enmFmt = AUD_FMT_S8;
     1682#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    16091683            break;
    16101684        case 1:
    1611             Log(("hda: %s requested 16-bit\n", __FUNCTION__));
    1612 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1613             *pFormat = AUD_FMT_S16;
    1614 # else
    1615             pAudSetting->fmt = AUD_FMT_S16;
    1616 # endif
     1685            LogFunc(("%s requested 16-bit\n", __FUNCTION__));
     1686#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1687            enmFmt = AUD_FMT_S16;
     1688#else
     1689            enmFmt = AUD_FMT_S16;
     1690#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    16171691            break;
    16181692        case 2:
    1619             Log(("hda: %s requested 20-bit\n", __FUNCTION__));
     1693            LogFunc(("%s requested 20-bit\n", __FUNCTION__));
    16201694            break;
    16211695        case 3:
    1622             Log(("hda: %s requested 24-bit\n", __FUNCTION__));
     1696            LogFunc(("%s requested 24-bit\n", __FUNCTION__));
    16231697            break;
    16241698        case 4:
    1625             Log(("hda: %s requested 32-bit\n", __FUNCTION__));
    1626 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1627             *pFormat = AUD_FMT_S32;
    1628 # else
    1629             pAudSetting->fmt = AUD_FMT_S32;
    1630 # endif
     1699            LogFunc(("%s requested 32-bit\n", __FUNCTION__));
     1700#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1701            enmFmt = AUD_FMT_S32;
     1702#else
     1703            enmFmt = AUD_FMT_S32;
     1704#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    16311705            break;
    16321706        default:
    1633             AssertMsgFailed(("Unsupported"));
    1634     }
    1635 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1636     *pChannels = (u32SdFmt & 0xf) + 1;
    1637     *pFormat = AUD_FMT_S16;
    1638     *pEndian = 0;
    1639 # else
    1640     pAudSetting->nchannels = (u32SdFmt & 0xf) + 1;
    1641     pAudSetting->fmt = AUD_FMT_S16;
    1642     pAudSetting->endianness = 0;
    1643 # endif
     1707            AssertMsgFailed(("Unsupported bits shift %x\n",
     1708                             EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT)));
     1709            rc = VERR_NOT_SUPPORTED;
     1710            break;
     1711    }
     1712
     1713    if (RT_SUCCESS(rc))
     1714    {
     1715#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1716        pCfg->uHz = u32Hz * u32HzMult / u32HzDiv;
     1717        pCfg->cChannels = (u32SdFmt & 0xf) + 1;
     1718        pCfg->enmFormat = enmFmt;
     1719        pCfg->enmEndianness = PDMAUDIOHOSTENDIANESS;
     1720#else
     1721        pCfg->nchannels = (u32SdFmt & 0xf) + 1;
     1722        pCfg->fmt = enmFmt;
     1723        pCfg->endianness = 0;
     1724#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1725    }
     1726
    16441727# undef EXTRACT_VALUE
     1728
     1729    return rc;
    16451730}
    16461731#endif
     
    16501735#ifdef IN_RING3
    16511736# ifdef VBOX_WITH_HDA_CODEC_EMU
    1652     /** @todo a bit more investigation is required here. */
    1653     int rc = 0;
    1654     /* no reason to reopen voice with same settings */
     1737    /* No reason to reopen voice with same settings. */
    16551738    if (u32Value == HDA_REG_IND(pThis, iReg))
    16561739        return VINF_SUCCESS;
    1657 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1658     uint32_t uFrequency;
    1659     uint32_t cChannels;
    1660     audfmt_e Format;
    1661     uint32_t Endian;
    1662     hdaSdFmtToAudSettings(u32Value, &uFrequency, &cChannels, &Format, &Endian);
    1663 # else
    1664     audsettings_t as;
    1665     hdaSdFmtToAudSettings(u32Value, &as);
    1666 # endif
     1740
     1741    PDMAUDIOSTREAMCFG as;
     1742    int rc = hdaSdFmtToAudSettings(u32Value, &as);
     1743    if (RT_FAILURE(rc))
     1744        return rc;
     1745
    16671746    switch (iReg)
    16681747    {
    16691748        case HDA_REG_SD0FMT:
    1670 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1671             for (uint32_t lun = 0; lun < 1; lun++)
    1672                 rc = hdaCodecOpenVoice(pThis->pCodec[lun], PI_INDEX, uFrequency, cChannels, Format, Endian);
    1673 # else
    1674             rc = hdaCodecOpenVoice(pThis->pCodec, PI_INDEX, &as);
    1675 # endif
     1749            for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     1750                rc = hdaCodecOpenStream(pThis->pCodec, PI_INDEX, &as);
    16761751            break;
    16771752        case HDA_REG_SD4FMT:
    1678 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1679             for (uint32_t lun = 0; lun < 1; lun++)
    1680                 rc = hdaCodecOpenVoice(pThis->pCodec[lun], PO_INDEX, uFrequency, cChannels, Format, Endian);
    1681 # else
    1682             rc = hdaCodecOpenVoice(pThis->pCodec, PO_INDEX, &as);
    1683 # endif
     1753            for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     1754                rc = hdaCodecOpenStream(pThis->pCodec, PO_INDEX, &as);
    16841755            break;
    16851756        default:
    1686             Log(("HDA: attempt to change format on %d\n", iReg));
    1687             rc = 0;
    1688     }
     1757            LogFunc(("Warning: Attempt to change format on register %d\n", iReg));
     1758            break;
     1759    }
     1760
     1761    /** @todo r=andy rc gets lost; needs fixing. */
    16891762    return hdaRegWriteU16(pThis, iReg, u32Value);
    16901763# else
     
    17261799static int hdaRegWriteIRS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    17271800{
    1728     int                         rc = VINF_SUCCESS;
     1801    int rc = VINF_SUCCESS;
    17291802
    17301803    /*
    1731      * if guest set the ICB bit of IRS register, HDA should process the verb in IC register,
     1804     * If the guest set the ICB bit of IRS register, HDA should process the verb in IC register,
    17321805     * write the response to IR register, and set the IRV (valid in case of success) bit of IRS register.
    17331806     */
     
    17441817             * 3.4.3 defines behavior of immediate Command status register.
    17451818             */
    1746             LogRel(("hda: guest attempted process immediate verb (%x) with active CORB\n", cmd));
     1819            LogRel(("guest attempted process immediate verb (%x) with active CORB\n", cmd));
    17471820            return rc;
    17481821        }
    17491822        HDA_REG(pThis, IRS) = HDA_REG_FIELD_FLAG_MASK(IRS, ICB);  /* busy */
    1750         Log(("hda: IC:%x\n", cmd));
    1751 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1752         for (uint32_t lun = 0; lun < 1; lun++)
    1753             rc = pThis->pCodec[lun]->pfnLookup(pThis->pCodec[lun], cmd, &pfn);
     1823        LogFunc(("IC:%x\n", cmd));
     1824# if 0
     1825        for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     1826        {
     1827            rc = pThis->pCodec[lun]->pfnLookup(pThis->pCodec[lun],
     1828                                               HDA_CODEC_CMD(cmd, lun),
     1829                                               &pfn);
     1830            if (RT_SUCCESS(rc))
     1831            {
     1832                AssertPtr(pfn);
     1833                rc = pfn(pThis->pCodec[lun],
     1834                         HDA_CODEC_CMD(cmd, lun), &resp);
     1835                if (RT_FAILURE(rc))
     1836                    break;
     1837            }
     1838        }
    17541839# else
    1755         rc = pThis->pCodec->pfnLookup(pThis->pCodec, cmd, &pfn);
    1756 # endif
     1840        rc = pThis->pCodec->pfnLookup(pThis->pCodec,
     1841                                      HDA_CODEC_CMD(cmd, 0 /* LUN */),
     1842                                      &pfn);
    17571843        if (RT_FAILURE(rc))
    17581844            AssertRCReturn(rc, rc);
    1759 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1760         for (uint32_t lun = 0; lun < 1; lun++)
    1761             rc = pfn(pThis->pCodec[lun], cmd, &resp);
    1762 #else
    1763         rc = pfn(pThis->pCodec, cmd, &resp);
    1764 #endif
     1845        rc = pfn(pThis->pCodec,
     1846                 HDA_CODEC_CMD(cmd, 0 /* LUN */), &resp);
     1847# endif
     1848
    17651849        if (RT_FAILURE(rc))
    17661850            AssertRCReturn(rc, rc);
    17671851        HDA_REG(pThis, IR) = (uint32_t)resp;
    1768         Log(("hda: IR:%x\n", HDA_REG(pThis, IR)));
     1852        LogFunc(("IR:%x\n", HDA_REG(pThis, IR)));
    17691853        HDA_REG(pThis, IRS) = HDA_REG_FIELD_FLAG_MASK(IRS, IRV);  /* result is ready  */
    17701854        HDA_REG(pThis, IRS) &= ~HDA_REG_FIELD_FLAG_MASK(IRS, ICB); /* busy is clear */
    1771 #else
     1855#else /* !IN_RING3 */
    17721856        rc = VINF_IOM_R3_MMIO_WRITE;
    17731857#endif
     
    18291913        default:
    18301914            AssertMsgFailed(("Invalid index"));
    1831     }
    1832     Log(("hda: CORB base:%llx RIRB base: %llx DP base: %llx\n", pThis->u64CORBBase, pThis->u64RIRBBase, pThis->u64DPBase));
     1915            break;
     1916    }
     1917
     1918    LogFunc(("CORB base:%llx RIRB base: %llx DP base: %llx\n",
     1919             pThis->u64CORBBase, pThis->u64RIRBBase, pThis->u64DPBase));
    18331920    return rc;
    18341921}
     
    18611948        len = *(uint32_t *)&bdle[8];
    18621949        ioc = *(uint32_t *)&bdle[12];
    1863         Log(("hda: %s bdle[%d] a:%llx, len:%d, ioc:%d\n",  (i == pBdle->u32BdleCvi? "[C]": "   "), i, addr, len, ioc & 0x1));
     1950        LogFunc(("%s bdle[%d] a:%llx, len:%d, ioc:%d\n",  (i == pBdle->u32BdleCvi? "[C]": "   "), i, addr, len, ioc & 0x1));
    18641951        sum += len;
    18651952    }
    1866     Log(("hda: sum: %d\n", sum));
     1953    LogFunc(("sum: %d\n", sum));
    18671954    for (i = 0; i < 8; ++i)
    18681955    {
    18691956        PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), (pThis->u64DPBase & DPBASE_ADDR_MASK) + i*8, &counter, sizeof(&counter));
    1870         Log(("hda: %s stream[%d] counter=%x\n", i == SDCTL_NUM(pThis, 4) || i == SDCTL_NUM(pThis, 0)? "[C]": "   ",
     1957        LogFunc(("%s stream[%d] counter=%x\n", i == SDCTL_NUM(pThis, 4) || i == SDCTL_NUM(pThis, 0)? "[C]": "   ",
    18711958             i , counter));
    18721959    }
     
    19182005                                                 uint32_t *pu32DMACursor, uint32_t *pu32BackendBufferCapacity)
    19192006{
    1920     Log(("hda:hdaBackendWriteTransferReported: cbArranged2Copy: %d, cbCopied: %d, pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n",
    1921         cbArranged2Copy, cbCopied, pu32DMACursor ? *pu32DMACursor : 0, pu32BackendBufferCapacity ? *pu32BackendBufferCapacity : 0));
     2007    LogFunc(("cbArranged2Copy: %d, cbCopied: %d, pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n",
     2008             cbArranged2Copy, cbCopied, pu32DMACursor ? *pu32DMACursor : 0, pu32BackendBufferCapacity ? *pu32BackendBufferCapacity : 0));
    19222009    Assert((cbCopied));
     2010    AssertPtr(pu32DMACursor);
    19232011    Assert((pu32BackendBufferCapacity && *pu32BackendBufferCapacity));
    19242012    /* Assertion!!! Fewer than cbUnderFifoW bytes were copied.
     
    19292017    if (   pBdle->cbUnderFifoW
    19302018        && pBdle->cbUnderFifoW <= cbCopied)
    1931         Log(("hda:hdaBackendWriteTransferReported: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     2019    {
     2020        LogFunc(("CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n",
     2021                 pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     2022    }
    19322023
    19332024    pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbCopied);
     
    19422033    /* Decrease the backend counter by the number of bytes we copied to the backend */
    19432034    *pu32BackendBufferCapacity -= cbCopied;
    1944     Log(("hda:hdaBackendWriteTransferReported: CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n",
    1945         pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, *pu32DMACursor, *pu32BackendBufferCapacity));
     2035    LogFunc(("CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n",
     2036             pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, *pu32DMACursor, *pu32BackendBufferCapacity));
    19462037}
    19472038
     
    19522043    *pu32BackendBufferCapacity -= cbCopied;
    19532044    pBdle->u32BdleCviPos += cbCopied;
    1954     Log(("hda:hdaBackendReadTransferReported: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     2045    LogFunc(("CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
    19552046    *pu32DMACursor += cbCopied + pBdle->cbUnderFifoW;
    19562047    pBdle->cbUnderFifoW = 0;
    1957     Log(("hda:hdaBackendReadTransferReported: CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n",
     2048    LogFunc(("CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n",
    19582049        pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, pu32DMACursor ? *pu32DMACursor : 0, pu32BackendBufferCapacity ? *pu32BackendBufferCapacity : 0));
    19592050}
     
    19622053                                              uint32_t cbCopied, uint32_t *pu32BackendBufferCapacity)
    19632054{
    1964     Log(("hda:hdaBackendTransferUnreported: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     2055    LogFunc(("CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
    19652056    pBdle->u32BdleCviPos += cbCopied;
    19662057    pBdle->cbUnderFifoW += cbCopied;
     
    19682059    if (pu32BackendBufferCapacity)
    19692060        *pu32BackendBufferCapacity -= cbCopied;
    1970     Log(("hda:hdaBackendTransferUnreported: CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     2061    LogFunc(("CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
    19712062    Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pThis, pStreamDesc)));
    19722063}
     
    20122103
    20132104        hdaUpdatePosBuf(pThis, pStreamDesc);
    2014 
    20152105    }
    20162106}
     
    20432133}
    20442134
    2045 /*
     2135#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2136/**
    20462137 * hdaReadAudio - copies samples from audio backend to DMA.
    2047  * Note: this function writes to the DMA buffer immediately, but "reports bytes" when all conditions are met (FIFOW)
     2138 * Note: This function writes to the DMA buffer immediately,
     2139 *       but "reports bytes" when all conditions are met (FIFOW).
    20482140 */
     2141static uint32_t hdaReadAudio(PHDASTATE pThis, PAUDMIXSINK pSink, PHDABDLEDESC pBdle,
     2142                             PHDASTREAMTRANSFERDESC pStreamDesc,
     2143                             uint32_t *pu32Avail, bool *fStop, uint32_t u32CblLimit)
     2144{
     2145    uint32_t cbTransferred = 0;
     2146
     2147    LogFlowFunc(("CVI(pos:%d, len:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     2148
     2149    uint32_t cb2Copy = hdaCalculateTransferBufferLength(pBdle, pStreamDesc, *pu32Avail, u32CblLimit);
     2150    if (!cb2Copy)
     2151    {
     2152        /* If we enter here we can't report "unreported bits". */
     2153        *fStop = true;
     2154    }
     2155    else
     2156    {
     2157        uint32_t cbRead = 0;
     2158        int rc = audioMixerProcessSinkIn(pSink, pBdle->au8HdaBuffer, cb2Copy, &cbRead);
     2159        if (RT_SUCCESS(rc))
     2160        {
     2161            /*
     2162             * Write the HDA DMA buffer.
     2163             */
     2164            PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns),
     2165                                  pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos,
     2166                                  pBdle->au8HdaBuffer, cbRead);
     2167
     2168            /* Don't see any reason why cb2Copy would differ from cbRead. */
     2169            Assert((cbRead == cb2Copy && (*pu32Avail) >= cb2Copy)); /* sanity */
     2170
     2171            if (pBdle->cbUnderFifoW + cbRead > hdaFifoWToSz(pThis, 0))
     2172                hdaBackendReadTransferReported(pBdle, cb2Copy, cbRead, &cbTransferred, pu32Avail);
     2173            else
     2174            {
     2175                hdaBackendTransferUnreported(pThis, pBdle, pStreamDesc, cbRead, pu32Avail);
     2176                *fStop = true;
     2177            }
     2178        }
     2179        else
     2180            *fStop = true;
     2181    }
     2182
     2183    Assert((cbTransferred <= (SDFIFOS(pThis, 0) + 1)));
     2184    LogFunc(("CVI(pos:%RU32, len:%RU32), cbTransferred: %RU32\n",
     2185             pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransferred));
     2186    return cbTransferred;
     2187}
     2188#else
    20492189static uint32_t hdaReadAudio(PHDASTATE pThis, PHDASTREAMTRANSFERDESC pStreamDesc, uint32_t *pu32Avail, bool *fStop, uint32_t u32CblLimit)
    20502190{
     
    20922232    return cbTransferred;
    20932233}
     2234#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    20942235
    20952236static uint32_t hdaWriteAudio(PHDASTATE pThis, PHDASTREAMTRANSFERDESC pStreamDesc, uint32_t *pu32Avail, bool *fStop, uint32_t u32CblLimit)
     
    20972238    PHDABDLEDESC pBdle = &pThis->StOutBdle;
    20982239    uint32_t cbTransferred = 0;
    2099     uint32_t cb2Copy = 0; /* local byte counter (on local buffer) */
    2100     uint32_t cbBackendCopy = 0; /* local byte counter, how many bytes copied to backend */
    2101 
    2102     Log(("hda:wa: CVI(cvi:%d, pos:%d, len:%d)\n", pBdle->u32BdleCvi, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
    2103 
    2104     cb2Copy = hdaCalculateTransferBufferLength(pBdle, pStreamDesc, *pu32Avail, u32CblLimit);
     2240    uint32_t cbWrittenMax = 0; /* local byte counter, how many bytes copied to backend */
     2241
     2242    LogFunc(("CVI(cvi:%RU32, pos:%RU32, len:%RU32)\n", pBdle->u32BdleCvi, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));
     2243
     2244    /* Local byte counter (on local buffer). */
     2245    uint32_t cb2Copy = hdaCalculateTransferBufferLength(pBdle, pStreamDesc, *pu32Avail, u32CblLimit);
    21052246
    21062247    /*
     
    21122253    else
    21132254    {
    2114         PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy);
     2255        PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns),
     2256                          pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos,
     2257                          pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy);
     2258
    21152259        /*
    2116          * Write to audio backend. we should ensure that we have enough bytes to copy to the backend.
     2260         * Write to audio backend. We should ensure that we have enough bytes to copy to the backend.
    21172261         */
    21182262        if (cb2Copy + pBdle->cbUnderFifoW >= hdaFifoWToSz(pThis, pStreamDesc))
    21192263        {
    2120             /*
    2121              * Feed the newly fetched samples, including unreported ones, to the backend.
    2122              */
    21232264#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2124             for (uint32_t lun = 0; lun < 1; lun++)
    2125                 cbBackendCopy = pThis->pDrv[lun]->pfnWrite(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW);
    2126             LogFlow(("cbBackendCopy write %d bytes \n", cbBackendCopy));
     2265            int rc;
     2266            uint32_t cbWritten;
     2267            for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     2268            {
     2269                rc = pThis->paDrv[lun]->pConnector->pfnWrite(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pGstStrmOut,
     2270                                                             pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW,
     2271                                                             &cbWritten);
     2272                if (RT_FAILURE(rc))
     2273                    continue;
     2274
     2275                cbWrittenMax = RT_MAX(cbWrittenMax, cbWritten);
     2276            }
    21272277#else
    2128             cbBackendCopy = AUD_write (pThis->pCodec->SwVoiceOut, pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW);
    2129 #endif
    2130             hdaBackendWriteTransferReported(pBdle, cb2Copy, cbBackendCopy, &cbTransferred, pu32Avail);
     2278            cbWrittenMax = AUD_write (pThis->pCodec->SwVoiceOut, pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW);
     2279#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     2280
     2281            hdaBackendWriteTransferReported(pBdle, cb2Copy, cbWrittenMax, &cbTransferred, pu32Avail);
    21312282        }
    21322283        else
    21332284        {
    2134             /* Not enough bytes to be processed and reported, we'll try our luck next time around */
     2285            /* Not enough bytes to be processed and reported, we'll try our luck next time around. */
    21352286            hdaBackendTransferUnreported(pThis, pBdle, pStreamDesc, cb2Copy, NULL);
    21362287            *fStop = true;
     
    21392290
    21402291    Assert(cbTransferred <= SDFIFOS(pThis, 4) + 1);
    2141     Log(("hda:wa: CVI(pos:%d, len:%d, cbTransferred:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransferred));
     2292    LogFunc(("CVI(pos:%RU32, len:%RU32, cbTransferred:%RU32)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransferred));
    21422293    return cbTransferred;
    21432294}
     
    21482299DECLCALLBACK(int) hdaCodecReset(PHDACODEC pCodec)
    21492300{
    2150     PHDASTATE pThis = (PHDASTATE)pCodec->pvHDAState;
     2301    PHDASTATE pThis = pCodec->pHDAState;
    21512302    NOREF(pThis);
    21522303    return VINF_SUCCESS;
     
    21582309    Assert(pThis); Assert(pBdle); Assert(pStreamDesc); Assert(u8Strm <= 7);
    21592310
    2160     memset(pStreamDesc, 0, sizeof(HDASTREAMTRANSFERDESC));
     2311    RT_BZERO(pStreamDesc, sizeof(HDASTREAMTRANSFERDESC));
    21612312    pStreamDesc->u8Strm     = u8Strm;
    21622313    pStreamDesc->u32Ctl     = HDA_STREAM_REG(pThis, CTL, u8Strm);
     
    21742325        && pBdle->u32BdleMaxCvi)
    21752326    {
    2176         Log(("Initialization of transfer descriptor:\n"));
     2327        LogFunc(("Initialization of transfer descriptor:\n"));
    21772328        dump_bd(pThis, pBdle, pStreamDesc->u64BaseDMA);
    21782329    }
     
    21802331}
    21812332
    2182 
    2183 /**
    2184  * @interface_method_impl{HDACODEC,pfnTransfer}
    2185  */
    2186 static DECLCALLBACK(void) hdaTransfer(PHDACODEC pCodec, ENMSOUNDSOURCE src, int avail)
    2187 {
    2188     PHDASTATE       pThis  = (PHDASTATE)pCodec->pvHDAState;
    2189     uint8_t         u8Strm = 0;
    2190     PHDABDLEDESC    pBdle  = NULL;
    2191 
    2192     switch (src)
    2193     {
     2333static DECLCALLBACK(void) hdaCloseIn(PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource)
     2334{
     2335    NOREF(pThis);
     2336    NOREF(enmRecSource);
     2337    LogFlowFuncEnter();
     2338}
     2339
     2340static DECLCALLBACK(void) hdaCloseOut(PHDASTATE pThis)
     2341{
     2342    NOREF(pThis);
     2343    LogFlowFuncEnter();
     2344}
     2345
     2346#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2347static void hdaMicInputCallback(void *pvDrv, uint32_t cbAvail)
     2348{
     2349    PHDADRIVER pThis = (PHDADRIVER)pvDrv;
     2350    hdaTransfer(pThis, MC_INDEX, cbAvail);
     2351}
     2352
     2353static void hdaLineInputCallback(void *pvDrv, uint32_t cbAvail)
     2354{
     2355    PHDADRIVER pThis = (PHDADRIVER)pvDrv;
     2356    hdaTransfer(pThis, PI_INDEX, cbAvail);
     2357}
     2358
     2359static void hdaOutputCallback(void *pvDrv, uint32_t cbFree)
     2360{
     2361    PHDADRIVER pThis = (PHDADRIVER)pvDrv;
     2362    hdaTransfer(pThis, PO_INDEX, cbFree);
     2363}
     2364
     2365static DECLCALLBACK(int) hdaOpenIn(PHDASTATE pThis,
     2366                                   const char *pszName, PDMAUDIORECSOURCE enmRecSource,
     2367                                   PPDMAUDIOSTREAMCFG pCfg)
     2368{
     2369    PDMAUDIOCALLBACK_FN pfnCallback;
     2370    PAUDMIXSINK pSink;
     2371
     2372    switch (enmRecSource)
     2373    {
     2374        case PDMAUDIORECSOURCE_MIC:
     2375            pfnCallback = hdaMicInputCallback;
     2376            pSink = pThis->pSinkMicIn;
     2377            break;
     2378        case PDMAUDIORECSOURCE_LINE_IN:
     2379            pfnCallback = hdaLineInputCallback;
     2380            pSink = pThis->pSinkLineIn;
     2381            break;
     2382        default:
     2383            AssertMsgFailed(("Audio source %ld not supported\n", enmRecSource));
     2384            return VERR_NOT_SUPPORTED;
     2385    }
     2386
     2387    int rc;
     2388    char *pszDesc;
     2389
     2390    Assert(pThis->cLUNs);
     2391    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     2392    {
     2393        if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] %s", lun, pszName) <= 0)
     2394        {
     2395            rc = VERR_NO_MEMORY;
     2396            break;
     2397        }
     2398
     2399        PHDADRIVER pDrv = pThis->paDrv[lun];
     2400        rc = pDrv->pConnector->pfnOpenIn(pDrv->pConnector,
     2401                                         pszDesc, enmRecSource,
     2402                                         pfnCallback /* fnCallback */, pDrv /* pvCallback */,
     2403                                         pCfg,
     2404                                         &pDrv->pStrmIn);
     2405        LogFlowFunc(("LUN#%RU8: Opened input \"%s\", with rc=%Rrc\n", lun, pszDesc, rc));
     2406        if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */
     2407        {
     2408            audioMixerRemoveStream(pSink, pDrv->phStrmIn);
     2409            rc = audioMixerAddStreamIn(pSink,
     2410                                       pDrv->pConnector, pDrv->pStrmIn,
     2411                                       0 /* uFlags */, &pDrv->phStrmIn);
     2412        }
     2413
     2414        RTStrFree(pszDesc);
     2415    }
     2416
     2417    LogFlowFuncLeaveRC(rc);
     2418    return rc;
     2419}
     2420
     2421static DECLCALLBACK(int) hdaOpenOut(PHDASTATE pThis,
     2422                                    const char *pszName, PPDMAUDIOSTREAMCFG pCfg)
     2423{
     2424    int rc;
     2425
     2426    Assert(pThis->cLUNs);
     2427    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     2428    {
     2429        PHDADRIVER pDrv = pThis->paDrv[lun];
     2430        rc = pDrv->pConnector->pfnOpenOut(pDrv->pConnector, pszName,
     2431                                          hdaOutputCallback /* fnCallback */, pDrv /* pvCallback */,
     2432                                          pCfg,
     2433                                          &pDrv->pGstStrmOut);
     2434    }
     2435
     2436    LogFlowFuncLeaveRC(rc);
     2437    return rc;
     2438}
     2439
     2440static DECLCALLBACK(int) hdaSetVolume(PHDASTATE pThis,
     2441                                      bool fMute, uint8_t uVolLeft, uint8_t uVolRight)
     2442{
     2443    int rc;
     2444
     2445    Assert(pThis->cLUNs);
     2446    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     2447    {
     2448        PHDADRIVER pDrv = pThis->paDrv[lun];
     2449        rc = pDrv->pConnector->pfnSetVolume(pDrv->pConnector,
     2450                                            fMute, uVolLeft, uVolRight);
     2451    }
     2452
     2453    LogFlowFuncLeaveRC(rc);
     2454    return rc;
     2455}
     2456#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     2457
     2458#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2459static DECLCALLBACK(void) hdaTransfer(PHDADRIVER pDrv,
     2460                                      ENMSOUNDSOURCE enmSrc, uint32_t cbAvail)
     2461{
     2462    AssertPtrReturnVoid(pDrv);
     2463    PHDASTATE pThis = pDrv->pHDAState;
     2464
     2465    LogFlowFunc(("pDrv=%p (LUN #%RU8), enmSrc=%ld, cbAvail=%RU32\n",
     2466                 pDrv, pDrv->uLUN, enmSrc, cbAvail));
     2467#else
     2468static DECLCALLBACK(void) hdaTransfer(PHDACODEC pCodec, ENMSOUNDSOURCE enmSrc, int cbAvail)
     2469{
     2470    AssertPtrReturnVoid(pCodec);
     2471    PHDASTATE pThis = pCodec->pHDAState;
     2472#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     2473    uint8_t      u8Strm;
     2474    PHDABDLEDESC pBdle;
     2475
     2476    switch (enmSrc)
     2477    {
     2478        case PI_INDEX:
     2479        {
     2480            u8Strm = 0;
     2481            pBdle = &pThis->StInBdle;
     2482            break;
     2483        }
     2484
     2485        case MC_INDEX:
     2486        {
     2487            u8Strm = 2;
     2488            pBdle = &pThis->StMicBdle;
     2489            break;
     2490        }
     2491
    21942492        case PO_INDEX:
    21952493        {
     
    21982496            break;
    21992497        }
    2200         case PI_INDEX:
    2201         {
    2202             u8Strm = 0;
    2203             pBdle = &pThis->StInBdle;
    2204             break;
    2205         }
     2498
    22062499        default:
     2500            AssertMsgFailed(("Unknown source index %ld\n", enmSrc));
    22072501            return;
    22082502    }
     
    22122506
    22132507    bool fStop = false;
    2214     while (avail && !fStop)
     2508    while (cbAvail && !fStop)
    22152509    {
    22162510        Assert(   (StreamDesc.u32Ctl & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN))
    2217                && avail
     2511               && cbAvail
    22182512               && StreamDesc.u64BaseDMA);
    22192513
    22202514        /* Fetch the Buffer Descriptor Entry (BDE). */
    2221 
    22222515        if (hdaIsTransferCountersOverlapped(pThis, pBdle, &StreamDesc))
    22232516            hdaFetchBdle(pThis, pBdle, &StreamDesc);
     2517
    22242518        *StreamDesc.pu32Sts |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);
    2225         Assert((avail >= 0 && (StreamDesc.u32Cbl >= (*StreamDesc.pu32Lpib)))); /* sanity */
     2519        Assert((cbAvail >= 0 && (StreamDesc.u32Cbl >= (*StreamDesc.pu32Lpib)))); /* sanity */
    22262520        uint32_t u32CblLimit = StreamDesc.u32Cbl - (*StreamDesc.pu32Lpib);
    22272521        Assert((u32CblLimit > hdaFifoWToSz(pThis, &StreamDesc)));
    2228         Log(("hda: CBL=%d, LPIB=%d\n", StreamDesc.u32Cbl, *StreamDesc.pu32Lpib));
     2522
     2523        LogFunc(("CBL=%RU32, LPIB=%RU32\n", StreamDesc.u32Cbl, *StreamDesc.pu32Lpib));
     2524
     2525#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2526        PAUDMIXSINK pSink;
     2527#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    22292528        uint32_t cb;
    2230         switch (src)
     2529        switch (enmSrc)
    22312530        {
     2531            case PI_INDEX:
     2532#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2533                pSink = pThis->pSinkLineIn;
     2534                cb = hdaReadAudio(pThis, pSink, pBdle, &StreamDesc, &cbAvail, &fStop, u32CblLimit);
     2535#else
     2536                cb = hdaReadAudio(pThis, &StreamDesc, (uint32_t *)&cbAvail, &fStop, u32CblLimit);
     2537#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     2538                break;
    22322539            case PO_INDEX:
    2233                 cb = hdaWriteAudio(pThis, &StreamDesc, (uint32_t *)&avail, &fStop, u32CblLimit);
     2540#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2541                cb = hdaWriteAudio(pThis, &StreamDesc, &cbAvail, &fStop, u32CblLimit);
     2542#else
     2543                cb = hdaWriteAudio(pThis, &StreamDesc, (uint32_t *)&cbAvail, &fStop, u32CblLimit);
     2544#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    22342545                break;
    2235             case PI_INDEX:
    2236                 cb = hdaReadAudio(pThis, &StreamDesc, (uint32_t *)&avail, &fStop, u32CblLimit);
     2546#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2547            case MC_INDEX:
     2548                pSink = pThis->pSinkMicIn;
     2549                cb = hdaReadAudio(pThis, pSink, pBdle, &StreamDesc, &cbAvail, &fStop, u32CblLimit);
    22372550                break;
     2551#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    22382552            default:
    22392553                cb = 0;
    22402554                fStop = true;
    2241                 AssertMsgFailed(("Unsupported"));
     2555                AssertMsgFailedReturnVoid(("Unsupported source index %d\n", enmSrc));
     2556                break;
    22422557        }
    22432558        Assert(cb <= StreamDesc.u32Fifos + 1);
     
    22492564    }
    22502565}
    2251 #endif
     2566#endif /* IN_RING3 */
    22522567
    22532568/* MMIO callbacks */
     
    22752590#endif
    22762591
    2277     Log(("hdaMMIORead: offReg=%#x cb=%#x\n", offReg, cb));
     2592    LogFunc(("offReg=%#x cb=%#x\n", offReg, cb));
    22782593#define NEW_READ_CODE
    22792594#ifdef NEW_READ_CODE
     
    22812596
    22822597    if (pThis->fInReset && idxRegDsc != HDA_REG_GCTL)
    2283         Log(("hda: access to registers except GCTL is blocked while reset\n"));
     2598        LogFunc(("access to registers except GCTL is blocked while reset\n"));
    22842599
    22852600    if (idxRegDsc == -1)
    2286         LogRel(("hda: Invalid read access @0x%x(of bytes:%d)\n", offReg, cb));
     2601        LogRel(("Invalid read access @0x%x(of bytes:%d)\n", offReg, cb));
    22872602
    22882603    if (idxRegDsc != -1)
     
    22952610             */
    22962611            rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, (uint32_t *)pv);
    2297             Log(("hda: read %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, rc));
     2612            LogFunc(("read %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, rc));
    22982613        }
    22992614        else
     
    23112626
    23122627                rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, &u32Tmp);
    2313                 Log(("hda: read %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, rc));
     2628                LogFunc(("read %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, rc));
    23142629                if (rc != VINF_SUCCESS)
    23152630                    break;
     
    23302645    {
    23312646        rc = VINF_IOM_MMIO_UNUSED_FF;
    2332         Log(("hda: hole at %x is accessed for read\n", offReg));
     2647        LogFunc(("hole at %x is accessed for read\n", offReg));
    23332648    }
    23342649#else
     
    23682683        rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, &u32Value);
    23692684        *(uint32_t *)pv |= (u32Value & mask);
    2370         Log(("hda: read %s[%x/%x]\n", g_aHdaRegMap[idxRegDsc].abbrev, u32Value, *(uint32_t *)pv));
     2685        LogFunc(("read %s[%x/%x]\n", g_aHdaRegMap[idxRegDsc].abbrev, u32Value, *(uint32_t *)pv));
    23712686    }
    23722687    else
    23732688    {
    23742689        *(uint32_t *)pv = 0xFF;
    2375         Log(("hda: hole at %x is accessed for read\n", offReg));
     2690        LogFunc(("hole at %x is accessed for read\n", offReg));
    23762691        rc = VINF_SUCCESS;
    23772692    }
     
    23832698#ifdef LOG_ENABLED
    23842699    if (cbLog == 4)
    2385         Log(("hdaMMIORead: @%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, rc));
     2700        LogFunc(("@%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, rc));
    23862701    else if (cbLog == 2)
    2387         Log(("hdaMMIORead: @%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, rc));
     2702        LogFunc(("@%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, rc));
    23882703    else if (cbLog == 1)
    2389         Log(("hdaMMIORead: @%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, rc));
     2704        LogFunc(("@%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, rc));
    23902705#endif
    23912706    return rc;
     
    23962711{
    23972712    if (pThis->fInReset && idxRegDsc != HDA_REG_GCTL)
    2398         Log(("hda: access to registers except GCTL is blocked while reset\n"));  /** @todo where is this enforced? */
     2713        LogFunc(("access to registers except GCTL is blocked while reset\n"));  /** @todo where is this enforced? */
    23992714
    24002715    uint32_t idxRegMem = g_aHdaRegMap[idxRegDsc].mem_idx;
     
    24032718#endif
    24042719    int rc = g_aHdaRegMap[idxRegDsc].pfnWrite(pThis, idxRegDsc, u32Value);
    2405     Log(("hda: write %#x -> %s[%db]; %x => %x%s\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev,
     2720    LogFunc(("write %#x -> %s[%db]; %x => %x%s\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev,
    24062721         g_aHdaRegMap[idxRegDsc].size, u32CurValue, pThis->au32Regs[idxRegMem], pszLog));
    24072722    return rc;
     
    24442759
    24452760#ifdef LOG_ENABLED
    2446     uint32_t const u32LogOldValue = idxRegDsc != -1 ? pThis->au32Regs[idxRegMem] : UINT32_MAX;
     2761    uint32_t const u32LogOldValue = idxRegDsc >= 0 ? pThis->au32Regs[idxRegMem] : UINT32_MAX;
    24472762    uint32_t const offRegLog = offReg;
    24482763    int      const idxRegLog = idxRegMem;
    24492764    if (idxRegDsc == -1)
    2450         Log(("hdaMMIOWrite: @%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb));
     2765        LogFunc(("@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb));
    24512766    else if (cb == 4)
    2452         Log(("hdaMMIOWrite: @%#05x u32=%#010x %s\n", offReg, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
     2767        LogFunc(("@%#05x u32=%#010x %s\n", offReg, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
    24532768    else if (cb == 2)
    2454         Log(("hdaMMIOWrite: @%#05x u16=%#06x (%#010x) %s\n", offReg, *(uint16_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
     2769        LogFunc(("@%#05x u16=%#06x (%#010x) %s\n", offReg, *(uint16_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
    24552770    else if (cb == 1)
    2456         Log(("hdaMMIOWrite: @%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
    2457     if (idxRegDsc != -1 && g_aHdaRegMap[idxRegDsc].size != cb)
    2458         Log(("hdaMMIOWrite: size=%d != cb=%d!!\n", g_aHdaRegMap[idxRegDsc].size, cb));
     2771        LogFunc(("@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
     2772    if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size != cb)
     2773        LogFunc(("size=%d != cb=%d!!\n", g_aHdaRegMap[idxRegDsc].size, cb));
    24592774#endif
    24602775
     
    24672782    {
    24682783        rc = hdaWriteReg(pThis, idxRegDsc, u64Value, "");
    2469         Log(("hdaMMIOWrite: @%#05x %#x -> %#x\n", offRegLog, u32LogOldValue,
     2784        LogFunc(("@%#05x %#x -> %#x\n", offRegLog, u32LogOldValue,
    24702785             idxRegLog != -1 ? pThis->au32Regs[idxRegLog] : UINT32_MAX));
    24712786    }
     
    24862801            u64Value <<= cbBefore * 8;
    24872802            u64Value  |= pThis->au32Regs[idxRegMem] & g_afMasks[cbBefore];
    2488             Log(("hdaMMIOWrite: Within register, supplied %u leading bits: %#llx -> %#llx ...\n",
     2803            LogFunc(("Within register, supplied %u leading bits: %#llx -> %#llx ...\n",
    24892804                 cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value));
    24902805        }
     
    25022817                {
    25032818                    u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbReg] & ~g_afMasks[cb];
    2504                     Log(("hdaMMIOWrite: Supplying missing bits (%#x): %#llx -> %#llx ...\n",
     2819                    LogFunc(("Supplying missing bits (%#x): %#llx -> %#llx ...\n",
    25052820                         g_afMasks[cbReg] & ~g_afMasks[cb], u64Value & g_afMasks[cb], u64Value));
    25062821                }
    25072822                uint32_t u32LogOldVal = pThis->au32Regs[idxRegMem];
    25082823                rc = hdaWriteReg(pThis, idxRegDsc, u64Value, "*");
    2509                 Log(("hdaMMIOWrite: @%#05x %#x -> %#x\n", offRegLog, u32LogOldVal,
     2824                LogFunc(("@%#05x %#x -> %#x\n", offRegLog, u32LogOldVal,
    25102825                     pThis->au32Regs[idxRegMem]));
    25112826            }
    25122827            else
    25132828            {
    2514                 LogRel(("hda: Invalid write access @0x%x!\n", offReg));
     2829                LogRel(("Invalid write access @0x%x!\n", offReg));
    25152830                cbReg = 1;
    25162831            }
     
    25822897
    25832898        rc = g_aHdaRegMap[idxRegDsc].pfnWrite(pThis, idxRegDsc, u32NewValue);
    2584         Log(("hda: write %s:(%x) %x => %x\n", g_aHdaRegMap[idxRegDsc].abbrev, u32NewValue,
     2899        LogFunc(("write %s:(%x) %x => %x\n", g_aHdaRegMap[idxRegDsc].abbrev, u32NewValue,
    25852900             u32CurValue, pThis->au32Regs[idxRegMem]));
    25862901    }
     
    25882903        rc = VINF_SUCCESS;
    25892904
    2590     Log(("hdaMMIOWrite: @%#05x %#x -> %#x\n", offRegLog, u32LogOldValue,
     2905    LogFunc(("@%#05x %#x -> %#x\n", offRegLog, u32LogOldValue,
    25912906         idxRegLog != -1 ? pThis->au32Regs[idxRegLog] : UINT32_MAX));
    25922907#endif
     
    26582973    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    26592974    /* Save Codec nodes states */
    2660 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2975#if 0
     2976    /** @todo Handle LUNs > 0! */
    26612977    hdaCodecSaveState(pThis->pCodec[0], pSSM);
    26622978#else
     
    26893005     * Load Codec nodes states.
    26903006     */
    2691 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     3007#if 0
     3008    /** @todo Handle LUNs > 0! */
    26923009    int rc = hdaCodecLoadState(pThis->pCodec[0], pSSM, uVersion);
    26933010#else
     
    27273044            rc = SSMR3GetU32(pSSM, &cRegs); AssertRCReturn(rc, rc);
    27283045            if (cRegs != RT_ELEMENTS(pThis->au32Regs))
    2729                 LogRel(("hda: cRegs is %d, expected %d\n", cRegs, RT_ELEMENTS(pThis->au32Regs)));
     3046                LogRel(("cRegs is %d, expected %d\n", cRegs, RT_ELEMENTS(pThis->au32Regs)));
    27303047            break;
    27313048
     
    27433060
    27443061    /*
    2745      * Load HDA dma counters.
     3062     * Load HDA DMA counters.
    27463063     */
    27473064    uint32_t   fFlags   = uVersion <= HDA_SSM_VERSION_2 ? SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED : 0;
    27483065    PCSSMFIELD paFields = uVersion <= HDA_SSM_VERSION_2 ? g_aHdaBDLEDescFieldsOld              : g_aHdaBDLEDescFields;
    2749     SSMR3GetStructEx(pSSM, &pThis->StOutBdle, sizeof(pThis->StOutBdle), fFlags, paFields, NULL);
    2750     SSMR3GetStructEx(pSSM, &pThis->StMicBdle, sizeof(pThis->StMicBdle), fFlags, paFields, NULL);
     3066    rc = SSMR3GetStructEx(pSSM, &pThis->StOutBdle, sizeof(pThis->StOutBdle), fFlags, paFields, NULL);
     3067    AssertRCReturn(rc, rc);
     3068    rc = SSMR3GetStructEx(pSSM, &pThis->StMicBdle, sizeof(pThis->StMicBdle), fFlags, paFields, NULL);
     3069    AssertRCReturn(rc, rc);
    27513070    rc = SSMR3GetStructEx(pSSM, &pThis->StInBdle, sizeof(pThis->StInBdle), fFlags, paFields, NULL);
    27523071    AssertRCReturn(rc, rc);
     
    27553074     * Update stuff after the state changes.
    27563075     */
     3076    bool fEnableIn    = RT_BOOL(SDCTL(pThis, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
     3077    bool fEnableMicIn = RT_BOOL(SDCTL(pThis, 2) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
     3078    bool fEnableOut   = RT_BOOL(SDCTL(pThis, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
     3079
    27573080#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2758     for (uint32_t lun = 0; lun < 1; lun++)
    2759     {
    2760         pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceIn, SDCTL(pThis, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
    2761         pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, SDCTL(pThis, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
     3081    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     3082    {
     3083        rc = pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn,
     3084                                                        fEnableIn);
     3085        if (RT_FAILURE(rc))
     3086            break;
     3087        rc = pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic,
     3088                                                        fEnableMicIn);
     3089        if (RT_FAILURE(rc))
     3090            break;
     3091        rc = pThis->paDrv[lun]->pConnector->pfnEnableOut(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pGstStrmOut,
     3092                                                         fEnableOut);
     3093        if (RT_FAILURE(rc))
     3094            break;
    27623095    }
    27633096#else
    27643097    AUD_set_active_in(pThis->pCodec->SwVoiceIn, SDCTL(pThis, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
    27653098    AUD_set_active_out(pThis->pCodec->SwVoiceOut, SDCTL(pThis, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
    2766 #endif
    2767 
    2768     pThis->u64CORBBase = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE));
    2769     pThis->u64RIRBBase = RT_MAKE_U64(HDA_REG(pThis, RIRBLBASE), HDA_REG(pThis, RIRBUBASE));
    2770     pThis->u64DPBase   = RT_MAKE_U64(HDA_REG(pThis, DPLBASE), HDA_REG(pThis, DPUBASE));
    2771     return VINF_SUCCESS;
     3099#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     3100
     3101    if (RT_SUCCESS(rc))
     3102    {
     3103        pThis->u64CORBBase = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE));
     3104        pThis->u64RIRBBase = RT_MAKE_U64(HDA_REG(pThis, RIRBLBASE), HDA_REG(pThis, RIRBUBASE));
     3105        pThis->u64DPBase   = RT_MAKE_U64(HDA_REG(pThis, DPLBASE), HDA_REG(pThis, DPUBASE));
     3106    }
     3107
     3108    LogFlowFuncLeaveRC(rc);
     3109    return rc;
    27723110}
    27733111
     
    28803218           && iHdaIndex >= 0
    28813219           && iHdaIndex < HDA_NREGS);
    2882     pHlp->pfnPrintf(pHlp, "hda: %s: 0x%x\n", g_aHdaRegMap[iHdaIndex].abbrev, pThis->au32Regs[g_aHdaRegMap[iHdaIndex].mem_idx]);
     3220    pHlp->pfnPrintf(pHlp, "%s: 0x%x\n", g_aHdaRegMap[iHdaIndex].abbrev, pThis->au32Regs[g_aHdaRegMap[iHdaIndex].mem_idx]);
    28833221}
    28843222
     
    29393277{
    29403278    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    2941 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2942     for (uint32_t lun = 0; lun < 1; lun++)
     3279#if 0
     3280    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     3281    {
    29433282        if (pThis->pCodec[lun]->pfnCodecDbgListNodes)
    29443283            pThis->pCodec[lun]->pfnCodecDbgListNodes(pThis->pCodec[lun], pHlp, pszArgs);
    29453284        else
    2946             pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
     3285            pHlp->pfnPrintf(pHlp, "Codec implementation for LUN #%RU8 doesn't provide corresponding callback\n", lun);
     3286    }
    29473287#else
    29483288    if (pThis->pCodec->pfnCodecDbgListNodes)
    29493289        pThis->pCodec->pfnCodecDbgListNodes(pThis->pCodec, pHlp, pszArgs);
    29503290    else
    2951         pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
     3291        pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback\n");
    29523292#endif
    29533293}
     
    29603300{
    29613301    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    2962 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2963     for (uint32_t lun = 0; lun < 1; lun++)
     3302#if 0
     3303    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     3304    {
    29643305        if (pThis->pCodec[lun]->pfnCodecDbgSelector)
    29653306            pThis->pCodec[lun]->pfnCodecDbgSelector(pThis->pCodec[lun], pHlp, pszArgs);
    29663307        else
    2967             pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
     3308            pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback\n");
     3309    }
    29683310#else
    29693311    if (pThis->pCodec->pfnCodecDbgSelector)
    29703312        pThis->pCodec->pfnCodecDbgSelector(pThis->pCodec, pHlp, pszArgs);
    29713313    else
    2972         pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
     3314        pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback\n");
    29733315#endif
    29743316}
     
    30013343 *          make sense to me so we'll do it.
    30023344 */
    3003 static DECLCALLBACK(void)  hdaReset(PPDMDEVINS pDevIns)
     3345static DECLCALLBACK(void) hdaReset(PPDMDEVINS pDevIns)
    30043346{
    30053347    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     
    30143356    HDA_REG(pThis, RIRBWP)   = 0x0;
    30153357
    3016     Log(("hda: inter HDA reset.\n"));
    3017 
     3358    LogFunc(("Resetting ...\n"));
     3359
     3360#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    30183361    /* Stop any audio currently playing. */
    3019 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    3020     for (uint32_t lun = 0; lun < 1; lun++)
    3021     {
    3022         pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceIn, false);
    3023         pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, false);
     3362    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     3363    {
     3364        pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn,
     3365                                                   false /* Disable */);
     3366        /* Ignore rc. */
     3367        pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic,
     3368                                                   false /* Disable */);
     3369        /* Ditto. */
     3370        pThis->paDrv[lun]->pConnector->pfnEnableOut(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pGstStrmOut,
     3371                                                    false /* Disable */);
     3372        /* Ditto. */
    30243373    }
    30253374#else
    30263375    AUD_set_active_in(pThis->pCodec->SwVoiceIn, false);
    30273376    AUD_set_active_out(pThis->pCodec->SwVoiceOut, false);
    3028 #endif
    3029 
     3377#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    30303378
    30313379    pThis->cbCorbBuf = 256 * sizeof(uint32_t);
    30323380
    30333381    if (pThis->pu32CorbBuf)
    3034         memset(pThis->pu32CorbBuf, 0, pThis->cbCorbBuf);
     3382        RT_ZERO(pThis->pu32CorbBuf);
    30353383    else
    30363384        pThis->pu32CorbBuf = (uint32_t *)RTMemAllocZ(pThis->cbCorbBuf);
     
    30383386    pThis->cbRirbBuf = 256 * sizeof(uint64_t);
    30393387    if (pThis->pu64RirbBuf)
    3040         memset(pThis->pu64RirbBuf, 0, pThis->cbRirbBuf);
     3388        RT_ZERO(pThis->pu64RirbBuf);
    30413389    else
    30423390        pThis->pu64RirbBuf = (uint64_t *)RTMemAllocZ(pThis->cbRirbBuf);
     
    30513399        if (u8Strm == 0)
    30523400            pBdle = &pThis->StInBdle;
     3401        else if (u8Strm == 2)
     3402            pBdle = &pThis->StMicBdle;
    30533403        else if(u8Strm == 4)
    30543404            pBdle = &pThis->StOutBdle;
    30553405        else
    30563406        {
    3057             memset(&StEmptyBdle, 0, sizeof(HDABDLEDESC));
     3407            RT_ZERO(StEmptyBdle);
    30583408            pBdle = &StEmptyBdle;
    30593409        }
     
    30673417    HDA_REG(pThis, STATESTS) = 0x1;
    30683418
    3069     Log(("hda: reset finished\n"));
    3070 }
    3071 
     3419    LogFunc(("Reset finished\n"));
     3420}
    30723421
    30733422/**
     
    30783427    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    30793428
     3429    if (pThis->pCodec)
     3430    {
     3431        int rc = hdaCodecDestruct(pThis->pCodec);
     3432        AssertRC(rc);
     3433
     3434        RTMemFree(pThis->pCodec);
     3435        pThis->pCodec = NULL;
     3436    }
     3437
    30803438#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    3081     for (uint32_t lun = 0; lun < 1; lun++)
    3082     {
    3083         if (pThis->pCodec[lun])
     3439    for (uint8_t lun = 0; lun < pThis->cLUNs; lun++)
     3440    {
     3441        if (pThis->paDrv[lun])
    30843442        {
    3085             int rc = hdaCodecDestruct(pThis->pCodec[lun]);
    3086             AssertRC(rc);
    3087             RTMemFree(pThis->pCodec[lun]);
    3088             pThis->pCodec[lun] = NULL;
     3443            RTMemFree(pThis->paDrv[lun]);
     3444            pThis->paDrv[lun] = NULL;
    30893445        }
    30903446    }
     3447
     3448    if (pThis->pMixer)
     3449    {
     3450        audioMixerDestroy(pThis->pMixer);
     3451        pThis->pMixer = NULL;
     3452    }
     3453
     3454    pThis->cLUNs = 0;
    30913455#else
    30923456    if (pThis->pCodec)
     
    30983462        pThis->pCodec = NULL;
    30993463    }
    3100 #endif
     3464#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    31013465
    31023466    RTMemFree(pThis->pu32CorbBuf);
     
    31083472    return VINF_SUCCESS;
    31093473}
     3474
     3475#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     3476/**
     3477 * Attach command.
     3478 *
     3479 * This is called to let the device attach to a driver for a specified LUN
     3480 * during runtime. This is not called during VM construction, the device
     3481 * constructor have to attach to all the available drivers.
     3482 *
     3483 * @returns VBox status code.
     3484 * @param   pDevIns     The device instance.
     3485 * @param   uLUN        The logical unit which is being detached.
     3486 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
     3487 */
     3488static DECLCALLBACK(int) hdaAttach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
     3489{
     3490    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     3491
     3492    AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
     3493                    ("HDA device does not support hotplugging\n"),
     3494                    VERR_INVALID_PARAMETER);
     3495
     3496    /*
     3497     * Attach driver.
     3498     */
     3499    char *pszDesc = NULL;
     3500    if (RTStrAPrintf(&pszDesc, "Audio driver port (HDA) for LUN #%u", uLUN) <= 0)
     3501        AssertMsgReturn(pszDesc,
     3502                        ("Not enough memory for HDA driver port description of LUN #%u\n", uLUN),
     3503                        VERR_NO_MEMORY);
     3504
     3505    int rc = PDMDevHlpDriverAttach(pDevIns, uLUN,
     3506                                   &pThis->IBase, &pThis->pDrvBase, pszDesc);
     3507    if (RT_SUCCESS(rc))
     3508    {
     3509        PHDADRIVER pDrv = (PHDADRIVER)RTMemAllocZ(sizeof(HDADRIVER));
     3510        if (pDrv)
     3511        {
     3512            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
     3513            AssertMsg(pDrv->pConnector != NULL,
     3514                      ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n",
     3515                      uLUN, rc));
     3516            pDrv->pHDAState = pThis;
     3517            pDrv->uLUN = uLUN;
     3518
     3519            pThis->paDrv[uLUN] = pDrv;
     3520            pThis->cLUNs++;
     3521        }
     3522        else
     3523            rc = VERR_NO_MEMORY;
     3524    }
     3525    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     3526    {
     3527        LogFunc(("No attached driver for LUN #%u\n", uLUN));
     3528    }
     3529    else if (RT_FAILURE(rc))
     3530        AssertMsgFailed(("Failed to attach HDA LUN #%u (\"%s\"), rc=%Rrc\n",
     3531                        uLUN, pszDesc, rc));
     3532
     3533    RTStrFree(pszDesc);
     3534
     3535    LogFlowFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
     3536    return rc;
     3537}
     3538
     3539static DECLCALLBACK(void) hdaDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     3540{
     3541    NOREF(pDevIns); NOREF(iLUN); NOREF(fFlags);
     3542
     3543    LogFlowFuncEnter();
     3544}
     3545#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    31103546
    31113547/**
     
    31143550static DECLCALLBACK(int) hdaConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
    31153551{
    3116     PHDASTATE   pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    3117     int         rc;
    3118 
     3552    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    31193553    Assert(iInstance == 0);
    31203554    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
     
    31283562                                N_ ("Invalid configuration for the Intel HDA device"));
    31293563
    3130     rc = CFGMR3QueryBoolDef(pCfgHandle, "RCEnabled", &pThis->fRCEnabled, false);
     3564    int rc = CFGMR3QueryBoolDef(pCfgHandle, "RCEnabled", &pThis->fRCEnabled, false);
    31313565    if (RT_FAILURE(rc))
    31323566        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    32513685    if (RT_FAILURE(rc))
    32523686        return rc;
     3687
    32533688#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    3254     //for (iter = 0; i < 3; i++)
    3255     {
    3256         /*
    3257         * Attach driver.
    3258         */
    3259         rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port");
     3689    /* We support 32 LUNs max. This should be enough for now. */
     3690    for (uint8_t lun = 0; lun < 32 ; lun++)
     3691    {
     3692        LogFunc(("Trying to attach driver for LUN #%RU32 ...\n", lun));
     3693        rc = hdaAttach(pDevIns, lun, PDM_TACH_FLAGS_NOT_HOT_PLUG);
     3694        if (RT_FAILURE(rc))
     3695        {
     3696            if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     3697                rc = VINF_SUCCESS;
     3698            break;
     3699        }
     3700    }
     3701
     3702    if (RT_SUCCESS(rc))
     3703    {
     3704        rc = audioMixerCreate("HDA Mixer", 0 /* uFlags */,
     3705                              &pThis->pMixer);
    32603706        if (RT_SUCCESS(rc))
    32613707        {
    3262             pThis->pDrv[0] = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
    3263             AssertMsgReturn(pThis->pDrv,
    3264                             ("Configuration error: instance %d has no host audio interface!\n", iInstance),
    3265                             VERR_PDM_MISSING_INTERFACE);
     3708            PDMAUDIOSTREAMCFG streamCfg;
     3709            streamCfg.uHz           = 48000;
     3710            streamCfg.cChannels     = 2;
     3711            streamCfg.enmFormat     = AUD_FMT_S16;
     3712            streamCfg.enmEndianness = PDMAUDIOHOSTENDIANESS;
     3713
     3714            rc = audioMixerSetDeviceFormat(pThis->pMixer, &streamCfg);
     3715            AssertRC(rc);
     3716
     3717            /* Add all required audio sinks. */
     3718            rc = audioMixerAddSink(pThis->pMixer, "[Recording] Line In",
     3719                                   &pThis->pSinkLineIn);
     3720            AssertRC(rc);
     3721
     3722            rc = audioMixerAddSink(pThis->pMixer, "[Recording] Microphone In",
     3723                                   &pThis->pSinkMicIn);
     3724            AssertRC(rc);
    32663725        }
    3267         else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    3268         {
    3269             Log(("ac97: No attached driver!\n"));
    3270         }
    3271         else if (RT_FAILURE(rc))
    3272         {
    3273             AssertMsgFailed(("Failed to attach AC97 LUN #0! rc=%Rrc\n", rc));
    3274             return rc;
    3275         }
    3276         rc = PDMDevHlpDriverAttach(pDevIns, 1, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port");
    3277         if (RT_SUCCESS(rc))
    3278         {
    3279             pThis->pDrv[1] = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
    3280             AssertMsgReturn(pThis->pDrv[1],
    3281                             ("Configuration error: instance %d has no host audio interface!\n", iInstance),
    3282                             VERR_PDM_MISSING_INTERFACE);
    3283         }
    3284         else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    3285         {
    3286             Log(("ac97: No attached driver! LUN#1\n"));
    3287         }
    3288         else if (RT_FAILURE(rc))
    3289         {
    3290             AssertMsgFailed(("Failed to attach AC97 LUN #1! rc=%Rrc\n", rc));
    3291             return rc;
    3292         }
    3293     }
     3726    }
     3727
     3728    LogFunc(("cLUNs=%RU8, rc=%Rrc\n", pThis->cLUNs, rc));
    32943729#else
    32953730    /*
     
    33043739        return rc;
    33053740    }
    3306 #endif
    3307     /* Construct codec state. */
     3741#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     3742
     3743    if (RT_SUCCESS(rc))
     3744    {
     3745        /* Construct codec. */
     3746        pThis->pCodec = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC));
     3747        if (!pThis->pCodec)
     3748            return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("Out of memory allocating HDA codec state"));
     3749
    33083750#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    3309     pThis->pCodec[0] = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC));
    3310     if (!pThis->pCodec[0])
    3311         return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("HDA: Out of memory allocating codec state"));
    3312     pThis->pCodec[1] = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC));
    3313     if (!pThis->pCodec[1])
    3314         return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("HDA: Out of memory allocating codec state"));
    3315 
    3316     pThis->pCodec[0]->pvHDAState = pThis;
    3317     pThis->pCodec[1]->pvHDAState = pThis;
    3318 
    3319     pThis->pCodec[0]->pDrv = pThis->pDrv[0];
    3320     //pThis->pCodec[1]->pDrv = pThis->pDrv[1];
    3321 
    3322     rc = hdaCodecConstruct(pDevIns, pThis->pCodec[0], pCfgHandle);
    3323     if (RT_FAILURE(rc))
    3324         AssertRCReturn(rc, rc);
    3325     rc = hdaCodecConstruct(pDevIns, pThis->pCodec[1], pCfgHandle);
    3326     if (RT_FAILURE(rc))
    3327         AssertRCReturn(rc, rc);
    3328 
    3329     /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for
    3330        verb F20 should provide device/codec recognition. */
    3331     Assert(pThis->pCodec[0]->u16VendorId);
    3332     Assert(pThis->pCodec[0]->u16DeviceId);
    3333     Assert(pThis->pCodec[1]->u16VendorId);
    3334     Assert(pThis->pCodec[1]->u16DeviceId);
    3335     PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec[0]->u16VendorId); /* 2c ro - intel.) */
    3336     PCIDevSetSubSystemId(      &pThis->PciDev, pThis->pCodec[0]->u16DeviceId); /* 2e ro. */
    3337     PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec[1]->u16VendorId); /* 2c ro - intel.) */
    3338     PCIDevSetSubSystemId(      &pThis->PciDev, pThis->pCodec[1]->u16DeviceId); /* 2e ro. */
    3339 
    3340     hdaReset(pDevIns);
    3341     pThis->pCodec[0]->id = 0;
    3342     pThis->pCodec[0]->pfnTransfer = hdaTransfer;
    3343     pThis->pCodec[0]->pfnReset = hdaCodecReset;
    3344     pThis->pCodec[1]->id = 0;
    3345     pThis->pCodec[1]->pfnTransfer = hdaTransfer;
    3346     pThis->pCodec[1]->pfnReset = hdaCodecReset;
    3347 #else
    3348     pThis->pCodec = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC));
    3349     if (!pThis->pCodec)
    3350         return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("HDA: Out of memory allocating codec state"));
    3351 
    3352     pThis->pCodec->pvHDAState = pThis;
    3353     rc = hdaCodecConstruct(pDevIns, pThis->pCodec, pCfgHandle);
    3354     if (RT_FAILURE(rc))
    3355         AssertRCReturn(rc, rc);
    3356 
    3357     /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for
    3358        verb F20 should provide device/codec recognition. */
    3359     Assert(pThis->pCodec->u16VendorId);
    3360     Assert(pThis->pCodec->u16DeviceId);
    3361     PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec->u16VendorId); /* 2c ro - intel.) */
    3362     PCIDevSetSubSystemId(      &pThis->PciDev, pThis->pCodec->u16DeviceId); /* 2e ro. */
    3363 
    3364     hdaReset(pDevIns);
    3365     pThis->pCodec->id = 0;
    3366     pThis->pCodec->pfnTransfer = hdaTransfer;
    3367     pThis->pCodec->pfnReset = hdaCodecReset;
    3368 
    3369     /*
    3370      * 18.2.6,7 defines that values of this registers might be cleared on power on/reset
    3371      * hdaReset shouldn't affects these registers.
    3372      */
    3373     HDA_REG(pThis, WAKEEN)   = 0x0;
    3374     HDA_REG(pThis, STATESTS) = 0x0;
    3375 #endif
    3376     /*
    3377      * Debug and string formatter types.
    3378      */
    3379     PDMDevHlpDBGFInfoRegister(pDevIns, "hda",         "HDA info. (hda [register case-insensitive])",    hdaInfo);
    3380     PDMDevHlpDBGFInfoRegister(pDevIns, "hdastrm",     "HDA stream info. (hdastrm [stream number])",     hdaInfoStream);
    3381     PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes",    "HDA codec nodes.",                               hdaInfoCodecNodes);
    3382     PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].",     hdaInfoCodecSelector);
    3383 
    3384     rc = RTStrFormatTypeRegister("sdctl",   hdaFormatStrmCtl,   NULL);
    3385     AssertRC(rc);
    3386     rc = RTStrFormatTypeRegister("sdsts",   hdaFormatStrmSts,   NULL);
    3387     AssertRC(rc);
    3388     rc = RTStrFormatTypeRegister("sdfifos", hdaFormatStrmFifos, NULL);
    3389     AssertRC(rc);
    3390     rc = RTStrFormatTypeRegister("sdfifow", hdaFormatStrmFifow, NULL);
    3391     AssertRC(rc);
    3392 #if 0
    3393     rc = RTStrFormatTypeRegister("sdfmt", printHdaStrmFmt, NULL);
    3394     AssertRC(rc);
    3395 #endif
    3396 
    3397     /*
    3398      * Some debug assertions.
    3399      */
    3400     for (unsigned i = 0; i < RT_ELEMENTS(g_aHdaRegMap); i++)
    3401     {
    3402         struct HDAREGDESC const *pReg     = &g_aHdaRegMap[i];
    3403         struct HDAREGDESC const *pNextReg = i + 1 < RT_ELEMENTS(g_aHdaRegMap) ?  &g_aHdaRegMap[i + 1] : NULL;
    3404 
    3405         /* binary search order. */
    3406         AssertReleaseMsg(!pNextReg || pReg->offset + pReg->size <= pNextReg->offset,
    3407                          ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
    3408                           i, pReg->offset, pReg->size, i + 1, pNextReg->offset, pNextReg->size));
    3409 
    3410         /* alignment. */
    3411         AssertReleaseMsg(   pReg->size == 1
    3412                          || (pReg->size == 2 && (pReg->offset & 1) == 0)
    3413                          || (pReg->size == 3 && (pReg->offset & 3) == 0)
    3414                          || (pReg->size == 4 && (pReg->offset & 3) == 0),
    3415                          ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
    3416 
    3417         /* registers are packed into dwords - with 3 exceptions with gaps at the end of the dword. */
    3418         AssertRelease(((pReg->offset + pReg->size) & 3) == 0 || pNextReg);
    3419         if (pReg->offset & 3)
     3751        /* Audio driver callbacks for multiplexing. */
     3752        pThis->pCodec->pfnCloseIn   = hdaCloseIn;
     3753        pThis->pCodec->pfnCloseOut  = hdaCloseOut;
     3754        pThis->pCodec->pfnOpenIn    = hdaOpenIn;
     3755        pThis->pCodec->pfnOpenOut   = hdaOpenOut;
     3756        pThis->pCodec->pfnSetVolume = hdaSetVolume;
     3757#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     3758
     3759        pThis->pCodec->pHDAState = pThis; /* Assign HDA controller state to codec. */
     3760
     3761        /* Construct the codec. */
     3762        rc = hdaCodecConstruct(pDevIns, pThis->pCodec, 0 /* Codec index */, pCfgHandle);
     3763        if (RT_FAILURE(rc))
     3764            AssertRCReturn(rc, rc);
     3765
     3766        /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for
     3767           verb F20 should provide device/codec recognition. */
     3768        Assert(pThis->pCodec->u16VendorId);
     3769        Assert(pThis->pCodec->u16DeviceId);
     3770        PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec->u16VendorId); /* 2c ro - intel.) */
     3771        PCIDevSetSubSystemId(      &pThis->PciDev, pThis->pCodec->u16DeviceId); /* 2e ro. */
     3772
     3773        pThis->pCodec->pfnTransfer = hdaTransfer;
     3774        pThis->pCodec->pfnReset = hdaCodecReset;
     3775    }
     3776
     3777    if (RT_SUCCESS(rc))
     3778    {
     3779        hdaReset(pDevIns);
     3780
     3781        /*
     3782         * 18.2.6,7 defines that values of this registers might be cleared on power on/reset
     3783         * hdaReset shouldn't affects these registers.
     3784         */
     3785        HDA_REG(pThis, WAKEEN)   = 0x0;
     3786        HDA_REG(pThis, STATESTS) = 0x0;
     3787
     3788        /*
     3789         * Debug and string formatter types.
     3790         */
     3791        PDMDevHlpDBGFInfoRegister(pDevIns, "hda",         "HDA info. (hda [register case-insensitive])",    hdaInfo);
     3792        PDMDevHlpDBGFInfoRegister(pDevIns, "hdastrm",     "HDA stream info. (hdastrm [stream number])",     hdaInfoStream);
     3793        PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes",    "HDA codec nodes.",                               hdaInfoCodecNodes);
     3794        PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].",     hdaInfoCodecSelector);
     3795
     3796        rc = RTStrFormatTypeRegister("sdctl",   hdaFormatStrmCtl,   NULL);
     3797        AssertRC(rc);
     3798        rc = RTStrFormatTypeRegister("sdsts",   hdaFormatStrmSts,   NULL);
     3799        AssertRC(rc);
     3800        rc = RTStrFormatTypeRegister("sdfifos", hdaFormatStrmFifos, NULL);
     3801        AssertRC(rc);
     3802        rc = RTStrFormatTypeRegister("sdfifow", hdaFormatStrmFifow, NULL);
     3803        AssertRC(rc);
     3804    #if 0
     3805        rc = RTStrFormatTypeRegister("sdfmt", printHdaStrmFmt, NULL);
     3806        AssertRC(rc);
     3807    #endif
     3808
     3809        /*
     3810         * Some debug assertions.
     3811         */
     3812        for (unsigned i = 0; i < RT_ELEMENTS(g_aHdaRegMap); i++)
    34203813        {
    3421             struct HDAREGDESC const *pPrevReg = i > 0 ?  &g_aHdaRegMap[i - 1] : NULL;
    3422             AssertReleaseMsg(pPrevReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
    3423             if (pPrevReg)
    3424                 AssertReleaseMsg(pPrevReg->offset + pPrevReg->size == pReg->offset,
    3425                                  ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
    3426                                   i - 1, pPrevReg->offset, pPrevReg->size, i + 1, pReg->offset, pReg->size));
     3814            struct HDAREGDESC const *pReg     = &g_aHdaRegMap[i];
     3815            struct HDAREGDESC const *pNextReg = i + 1 < RT_ELEMENTS(g_aHdaRegMap) ?  &g_aHdaRegMap[i + 1] : NULL;
     3816
     3817            /* binary search order. */
     3818            AssertReleaseMsg(!pNextReg || pReg->offset + pReg->size <= pNextReg->offset,
     3819                             ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
     3820                              i, pReg->offset, pReg->size, i + 1, pNextReg->offset, pNextReg->size));
     3821
     3822            /* alignment. */
     3823            AssertReleaseMsg(   pReg->size == 1
     3824                             || (pReg->size == 2 && (pReg->offset & 1) == 0)
     3825                             || (pReg->size == 3 && (pReg->offset & 3) == 0)
     3826                             || (pReg->size == 4 && (pReg->offset & 3) == 0),
     3827                             ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
     3828
     3829            /* registers are packed into dwords - with 3 exceptions with gaps at the end of the dword. */
     3830            AssertRelease(((pReg->offset + pReg->size) & 3) == 0 || pNextReg);
     3831            if (pReg->offset & 3)
     3832            {
     3833                struct HDAREGDESC const *pPrevReg = i > 0 ?  &g_aHdaRegMap[i - 1] : NULL;
     3834                AssertReleaseMsg(pPrevReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
     3835                if (pPrevReg)
     3836                    AssertReleaseMsg(pPrevReg->offset + pPrevReg->size == pReg->offset,
     3837                                     ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
     3838                                      i - 1, pPrevReg->offset, pPrevReg->size, i + 1, pReg->offset, pReg->size));
     3839            }
     3840    #if 0
     3841            if ((pReg->offset + pReg->size) & 3)
     3842            {
     3843                AssertReleaseMsg(pNextReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
     3844                if (pNextReg)
     3845                    AssertReleaseMsg(pReg->offset + pReg->size == pNextReg->offset,
     3846                                     ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
     3847                                      i, pReg->offset, pReg->size, i + 1,  pNextReg->offset, pNextReg->size));
     3848            }
     3849    #endif
     3850
     3851            /* The final entry is a full dword, no gaps! Allows shortcuts. */
     3852            AssertReleaseMsg(pNextReg || ((pReg->offset + pReg->size) & 3) == 0,
     3853                             ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
    34273854        }
    3428 #if 0
    3429         if ((pReg->offset + pReg->size) & 3)
    3430         {
    3431             AssertReleaseMsg(pNextReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
    3432             if (pNextReg)
    3433                 AssertReleaseMsg(pReg->offset + pReg->size == pNextReg->offset,
    3434                                  ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
    3435                                   i, pReg->offset, pReg->size, i + 1,  pNextReg->offset, pNextReg->size));
    3436         }
    3437 #endif
    3438 
    3439         /* The final entry is a full dword, no gaps! Allows shortcuts. */
    3440         AssertReleaseMsg(pNextReg || ((pReg->offset + pReg->size) & 3) == 0,
    3441                          ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
    3442     }
    3443 
    3444     return VINF_SUCCESS;
     3855    }
     3856
     3857    LogFlowFuncLeaveRC(rc);
     3858    return rc;
    34453859}
    34463860
  • trunk/src/VBox/Devices/Audio/DevIchHdaCodec.cpp

    r51636 r53442  
    99
    1010/*
    11  * Copyright (C) 2006-2013 Oracle Corporation
     11 * Copyright (C) 2006-2014 Oracle Corporation
    1212 *
    1313 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2424*   Header Files                                                               *
    2525*******************************************************************************/
    26 #define LOG_GROUP LOG_GROUP_DEV_AUDIO
     26//#define LOG_GROUP LOG_GROUP_DEV_AUDIO
    2727#include <VBox/vmm/pdmdev.h>
    28 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2928#include <VBox/vmm/pdmaudioifs.h>
    30 #endif
    3129#include <iprt/assert.h>
    3230#include <iprt/uuid.h>
     
    4947*******************************************************************************/
    5048/* PRM 5.3.1 */
     49/** Codec address mask. */
    5150#define CODEC_CAD_MASK              0xF0000000
     51/** Codec address shift. */
    5252#define CODEC_CAD_SHIFT             28
    5353#define CODEC_DIRECT_MASK           RT_BIT(27)
     54/** Node ID mask. */
    5455#define CODEC_NID_MASK              0x07F00000
     56/** Node ID shift. */
    5557#define CODEC_NID_SHIFT             20
    5658#define CODEC_VERBDATA_MASK         0x000FFFFF
     
    6264#define CODEC_VERB_16BIT_DATA       0x0000FFFF
    6365
    64 #define CODEC_CAD(cmd) ((cmd) & CODEC_CAD_MASK)
     66#define CODEC_CAD(cmd) (((cmd) & CODEC_CAD_MASK) >> CODEC_CAD_SHIFT)
    6567#define CODEC_DIRECT(cmd) ((cmd) & CODEC_DIRECT_MASK)
    6668#define CODEC_NID(cmd) ((((cmd) & CODEC_NID_MASK)) >> CODEC_NID_SHIFT)
     
    10961098    pThis->u8AssemblyId = 0x80;
    10971099    pThis->paNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pThis->cTotalNodes);
     1100    if (!pThis->paNodes)
     1101        return VERR_NO_MEMORY;
    10981102    pThis->fInReset = false;
    10991103#define STAC9220WIDGET(type) pThis->au8##type##s = g_abStac9220##type##s
     
    11641168 */
    11651169#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1166 static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, audmixerctl_t mt)
     1170static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL mt)
    11671171#else
    11681172static int hdaCodecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt)
     
    11721176    switch (mt)
    11731177    {
     1178#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1179        case PDMAUDIOMIXERCTL_VOLUME:
     1180        case PDMAUDIOMIXERCTL_PCM:
     1181#else
    11741182        case AUD_MIXER_VOLUME:
    11751183        case AUD_MIXER_PCM:
     1184#endif
    11761185            dir = AMPLIFIER_OUT;
    11771186            break;
     1187#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1188        case PDMAUDIOMIXERCTL_LINE_IN:
     1189#else
    11781190        case AUD_MIXER_LINE_IN:
     1191#endif
    11791192            dir = AMPLIFIER_IN;
    11801193            break;
    1181     }
     1194        default:
     1195            AssertMsgFailed(("Invalid mixer control %ld\n", mt));
     1196            break;
     1197    }
     1198
    11821199    int mute = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & RT_BIT(7);
    11831200    mute |= AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & RT_BIT(7);
     
    11861203    uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & 0x7f;
    11871204    uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & 0x7f;
     1205
    11881206#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1189      /* @todo in SetVolume no passing audmixerctl_in as its not used in DrvAudio.c */
    1190     pThis->pDrv->pfnSetVolume(pThis->pDrv, &mute, &lVol, &rVol);
     1207    /** @todo In SetVolume no passing audmixerctl_in as its not used in DrvAudio.cpp. */
     1208    pThis->pfnSetVolume(pThis->pHDAState, RT_BOOL(mute), lVol, rVol);
    11911209#else
    11921210    AUD_set_volume(mt, &mute, &lVol, &rVol);
     
    12191237static DECLCALLBACK(int) vrbProcUnimplemented(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    12201238{
    1221     Log(("vrbProcUnimplemented: cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd,
     1239    LogFlowFunc(("cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd,
    12221240        CODEC_CAD(cmd), CODEC_DIRECT(cmd) ? 'N' : 'Y', CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
    12231241    *pResp = 0;
     
    12401258    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    12411259    {
    1242         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1260        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    12431261        return VINF_SUCCESS;
    12441262    }
     
    12951313    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    12961314    {
    1297         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1315        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    12981316        return VINF_SUCCESS;
    12991317    }
     
    13401358    if (CODEC_NID(cmd) == pThis->u8DacLineOut)
    13411359#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1342         hdaCodecToAudVolume(pThis, pAmplifier, AUD_MIXER_VOLUME);
     1360        hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_VOLUME);
    13431361#else
    13441362        hdaCodecToAudVolume(pAmplifier, AUD_MIXER_VOLUME);
    13451363#endif
     1364
    13461365    if (CODEC_NID(cmd) == pThis->u8AdcVolsLineIn) /* Microphone */
    13471366#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1348         hdaCodecToAudVolume(pThis, pAmplifier, AUD_MIXER_LINE_IN);
     1367        hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
    13491368#else
    13501369        hdaCodecToAudVolume(pAmplifier, AUD_MIXER_LINE_IN);
    13511370#endif
     1371
    13521372    return VINF_SUCCESS;
    13531373}
     
    13581378    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    13591379    {
    1360         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1380        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    13611381        return VINF_SUCCESS;
    13621382    }
     
    13641384    if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F00_PARAM_LENGTH)
    13651385    {
    1366         Log(("HdaCodec: invalid F00 parameter %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
     1386        LogFlowFunc(("invalid F00 parameter %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
    13671387        return VINF_SUCCESS;
    13681388    }
     
    13781398    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    13791399    {
    1380         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1400        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    13811401        return VINF_SUCCESS;
    13821402    }
     
    14011421    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    14021422    {
    1403         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1423        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    14041424        return VINF_SUCCESS;
    14051425    }
     
    14291449    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    14301450    {
    1431         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1451        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    14321452        return VINF_SUCCESS;
    14331453    }
     
    14571477    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    14581478    {
    1459         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1479        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    14601480        return VINF_SUCCESS;
    14611481    }
     
    14881508    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    14891509    {
    1490         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1510        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    14911511        return VINF_SUCCESS;
    14921512    }
     
    15161536    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    15171537    {
    1518         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1538        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    15191539        return VINF_SUCCESS;
    15201540    }
     
    15461566    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    15471567    {
    1548         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1568        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    15491569        return VINF_SUCCESS;
    15501570    }
     
    15661586    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    15671587    {
    1568         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1588        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    15691589        return VINF_SUCCESS;
    15701590    }
     
    15881608    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    15891609    {
    1590         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1610        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    15911611        return VINF_SUCCESS;
    15921612    }
     
    15941614    if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F02_PARAM_LENGTH)
    15951615    {
    1596         Log(("HdaCodec: access to invalid F02 index %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
     1616        LogFlowFunc(("access to invalid F02 index %d\n", (cmd & CODEC_VERB_8BIT_DATA)));
    15971617        return VINF_SUCCESS;
    15981618    }
     
    16081628    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    16091629    {
    1610         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1630        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    16111631        return VINF_SUCCESS;
    16121632    }
     
    16241644    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    16251645    {
    1626         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1646        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    16271647        return VINF_SUCCESS;
    16281648    }
     
    16401660    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    16411661    {
    1642         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1662        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    16431663        return VINF_SUCCESS;
    16441664    }
     
    16571677    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    16581678    {
    1659         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1679        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    16601680        return VINF_SUCCESS;
    16611681    }
     
    16871707    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    16881708    {
    1689         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1709        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    16901710        return VINF_SUCCESS;
    16911711    }
     
    17031723    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    17041724    {
    1705         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1725        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    17061726        return VINF_SUCCESS;
    17071727    }
     
    17511771    {
    17521772        uint8_t i;
    1753         Log(("HdaCodec: enters reset\n"));
     1773        LogFlowFunc(("enters reset\n"));
    17541774        Assert(pThis->pfnCodecNodeReset);
    17551775        for (i = 0; i < pThis->cTotalNodes; ++i)
     
    17581778        }
    17591779        pThis->fInReset = false;
    1760         Log(("HdaCodec: exits reset\n"));
     1780        LogFlowFunc(("exits reset\n"));
    17611781    }
    17621782    *pResp = 0;
     
    17711791    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    17721792    {
    1773         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1793        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    17741794        return VINF_SUCCESS;
    17751795    }
     
    18111831    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    18121832    {
    1813         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1833        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    18141834        return VINF_SUCCESS;
    18151835    }
     
    18771897    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    18781898    {
    1879         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1899        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    18801900        return VINF_SUCCESS;
    18811901    }
     
    19001920    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    19011921    {
    1902         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1922        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    19031923        return VINF_SUCCESS;
    19041924    }
     
    19271947    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    19281948    {
    1929         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1949        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    19301950        return VINF_SUCCESS;
    19311951    }
     
    19481968    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    19491969    {
    1950         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1970        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    19511971        return VINF_SUCCESS;
    19521972    }
     
    19701990    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    19711991    {
    1972         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     1992        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    19731993        return VINF_SUCCESS;
    19741994    }
     
    19902010    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    19912011    {
    1992         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     2012        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    19932013        return VINF_SUCCESS;
    19942014    }
     
    20162036    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    20172037    {
    2018         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     2038        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    20192039        return VINF_SUCCESS;
    20202040    }
     
    20322052    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    20332053    {
    2034         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     2054        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    20352055        return VINF_SUCCESS;
    20362056    }
     
    20522072    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    20532073    {
    2054         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     2074        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    20552075        return VINF_SUCCESS;
    20562076    }
     
    20692089    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    20702090    {
    2071         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     2091        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    20722092        return VINF_SUCCESS;
    20732093    }
     
    20892109    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    20902110    {
    2091         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     2111        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    20922112        return VINF_SUCCESS;
    20932113    }
     
    21142134    if (CODEC_NID(cmd) >= pThis->cTotalNodes)
    21152135    {
    2116         Log(("HdaCodec: invalid node address %d\n", CODEC_NID(cmd)));
     2136        LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd)));
    21172137        return VINF_SUCCESS;
    21182138    }
     
    22192239    Assert(CODEC_CAD(cmd) == pThis->id);
    22202240    if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd)))
    2221         Log(("HdaCodec: cmd %x was addressed to reserved node\n", cmd));
     2241        LogFlowFunc(("cmd %x was addressed to reserved node\n", cmd));
    22222242
    22232243    if (   CODEC_VERBDATA(cmd) == 0
     
    22262246        *pfn = vrbProcUnimplemented;
    22272247        /// @todo r=michaln: There needs to be a counter to avoid log flooding (see e.g. DevRTC.cpp)
    2228         Log(("HdaCodec: cmd %x was ignored\n", cmd));
     2248        LogFlowFunc(("cmd %x was ignored\n", cmd));
    22292249        return VINF_SUCCESS;
    22302250    }
     
    22402260
    22412261    *pfn = vrbProcUnimplemented;
    2242     Log(("HdaCodec: callback for %x wasn't found\n", CODEC_VERBDATA(cmd)));
    2243     return VINF_SUCCESS;
    2244 }
    2245 
     2262    LogFlowFunc(("callback for %x wasn't found\n", CODEC_VERBDATA(cmd)));
     2263    return VINF_SUCCESS;
     2264}
     2265
     2266#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    22462267static void pi_callback(void *opaque, int avail)
    22472268{
     
    22552276    pThis->pfnTransfer(pThis, PO_INDEX, avail);
    22562277}
    2257 
     2278#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    22582279
    22592280/*
     
    22712292 */
    22722293#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2273 int hdaCodecOpenVoice(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, uint32_t uFrequency, uint32_t cChannels,
    2274                       audfmt_e fmt, uint32_t Endian)
     2294int hdaCodecOpenStream(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, PPDMAUDIOSTREAMCFG pCfg)
    22752295#else
    2276 int hdaCodecOpenVoice(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, audsettings_t *pAudioSettings)
     2296int hdaCodecOpenStream(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, audsettings_t *pAudioSettings)
    22772297#endif
    22782298{
     2299    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     2300
    22792301    int rc;
    2280 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2281     Assert(pThis);
    2282     if (!pThis)
    2283         return -1;
    2284 #else
    2285     Assert(pThis && pAudioSettings);
    2286     if (   !pThis
    2287         || !pAudioSettings)
    2288         return -1;
    2289 #endif
     2302
    22902303    switch (enmSoundSource)
    22912304    {
     
    22932306#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    22942307            /* old and new stream settings are not same. Then only call open */
    2295 
    22962308            //if (!hdaCodecCompareAudioSettings(&(pThis->SwVoiceIn)->info, pAudioSettings) && !pThis->SwVoiceIn)
    2297                 rc = pThis->pDrv->pfnOpenIn(pThis->pDrv, &pThis->SwVoiceIn, "hda.in", pThis, pi_callback, uFrequency,
    2298                                             cChannels, fmt, Endian);
     2309                rc = pThis->pfnOpenIn(pThis->pHDAState, "hda.in",
     2310                                      PDMAUDIORECSOURCE_LINE_IN, pCfg);
    22992311#else
    2300             pThis->SwVoiceIn = AUD_open_in(&pThis->card, pThis->SwVoiceIn, "hda.in", pThis, pi_callback, pAudioSettings);
     2312                pThis->SwVoiceIn = AUD_open_in(&pThis->card, pThis->SwVoiceIn, "hda.in", pThis, pi_callback, pAudioSettings);
     2313                rc = pThis->SwVoiceIn ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
    23012314#endif
    2302             rc = pThis->SwVoiceIn ? 0 : 1;
    2303             break;
     2315            break;
     2316
    23042317        case PO_INDEX:
    23052318#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2306             rc = pThis->pDrv->pfnOpenOut(pThis->pDrv, &pThis->SwVoiceOut, "hda.out", pThis, po_callback, uFrequency,
    2307                                          cChannels, fmt, Endian);
     2319            rc = pThis->pfnOpenOut(pThis->pHDAState, "hda.out", pCfg);
    23082320#else
    23092321            pThis->SwVoiceOut = AUD_open_out(&pThis->card, pThis->SwVoiceOut, "hda.out", pThis, po_callback, pAudioSettings);
     2322            rc = pThis->SwVoiceOut ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
    23102323#endif
    2311             rc = pThis->SwVoiceOut ? 0 : 1;
    2312             break;
     2324            break;
     2325
     2326#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2327        case MC_INDEX:
     2328            /* old and new stream settings are not same. Then only call open */
     2329            //if (!hdaCodecCompareAudioSettings(&(pThis->SwVoiceIn)->info, pAudioSettings) && !pThis->SwVoiceIn)
     2330                rc = pThis->pfnOpenIn(pThis->pHDAState, "hda.mc",
     2331                                      PDMAUDIORECSOURCE_MIC, pCfg);
     2332            break;
     2333#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     2334
    23132335        default:
    2314             return -1;
    2315     }
    2316     if (!rc)
    2317 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2318         LogRel(("HdaCodec: Can't open %s fmt(freq: %d)\n", enmSoundSource == PI_INDEX? "in" : "out", uFrequency));
    2319 #else
    2320         LogRel(("HdaCodec: Can't open %s fmt(freq: %d)\n", enmSoundSource == PI_INDEX? "in" : "out", pAudioSettings->freq));
    2321 #endif
     2336            AssertMsgFailed(("Index %ld not implemented\n", enmSoundSource));
     2337            rc = VERR_NOT_IMPLEMENTED;
     2338    }
     2339
     2340    LogFlowFuncLeaveRC(rc);
    23222341    return rc;
    23232342}
    2324 
    23252343
    23262344int hdaCodecSaveState(PHDACODEC pThis, PSSMHANDLE pSSM)
     
    23342352    return VINF_SUCCESS;
    23352353}
    2336 
    23372354
    23382355int hdaCodecLoadState(PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion)
     
    23912408    if (hdaCodecIsDacNode(pThis, pThis->u8DacLineOut))
    23922409#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2393         hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
     2410        hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_VOLUME);
    23942411#else
    23952412        hdaCodecToAudVolume(&pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
     
    23972414    else if (hdaCodecIsSpdifOutNode(pThis, pThis->u8DacLineOut))
    23982415#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2399         hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, AUD_MIXER_VOLUME);
    2400     hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
     2416        hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, PDMAUDIOMIXERCTL_VOLUME);
     2417    hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
    24012418#else
    24022419        hdaCodecToAudVolume(&pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, AUD_MIXER_VOLUME);
     
    24072424}
    24082425
    2409 
    24102426int hdaCodecDestruct(PHDACODEC pThis)
    24112427{
    2412     RTMemFree(pThis->paNodes);
    2413     pThis->paNodes = NULL;
    2414     return VINF_SUCCESS;
    2415 }
    2416 
    2417 
    2418 int hdaCodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, PCFGMNODE pCfg)
    2419 {
     2428    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     2429
     2430    if (pThis->paNodes)
     2431    {
     2432        RTMemFree(pThis->paNodes);
     2433        pThis->paNodes = NULL;
     2434    }
     2435
     2436    return VINF_SUCCESS;
     2437}
     2438
     2439int hdaCodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis,
     2440                      uint16_t uLUN, PCFGMNODE pCfg)
     2441{
     2442    AssertPtrReturn(pDevIns, VERR_INVALID_POINTER);
     2443    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     2444    AssertPtrReturn(pCfg, VERR_INVALID_POINTER);
     2445
     2446    pThis->id        = uLUN;
    24202447    pThis->paVerbs   = &g_aCodecVerbs[0];
    24212448    pThis->cVerbs    = RT_ELEMENTS(g_aCodecVerbs);
     
    24232450    int rc = stac9220Construct(pThis);
    24242451    AssertRC(rc);
    2425 
    24262452
    24272453    /* common root node initializers */
     
    24332459    pThis->paNodes[1].afg.u32F20_param = CODEC_MAKE_F20(pThis->u16VendorId, pThis->u8BSKU, pThis->u8AssemblyId);
    24342460
    2435     /// @todo r=michaln: Was this meant to be 'HDA' or something like that? (AC'97 was on ICH0)
    24362461#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2437     pThis->pDrv->pfnRegisterCard(pThis->pDrv, "ICH0");
     2462    /* 44.1 kHz. */
     2463    PDMAUDIOSTREAMCFG as;
     2464    as.uHz           = 44100;
     2465    as.cChannels     = 2;
     2466    as.enmFormat     = AUD_FMT_S16;
     2467    as.enmEndianness = PDMAUDIOHOSTENDIANESS;
    24382468#else
    24392469    AUD_register_card("ICH0", &pThis->card);
     
    24482478
    24492479    pThis->paNodes[1].node.au32F00_param[0xA] = CODEC_F00_0A_16_BIT;
    2450 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2451     hdaCodecOpenVoice(pThis, PI_INDEX, 44100, 2, AUD_FMT_S16, 0);
    2452     hdaCodecOpenVoice(pThis, PO_INDEX, 44100, 2, AUD_FMT_S16, 0);
    2453 #else
    2454     hdaCodecOpenVoice(pThis, PI_INDEX, &as);
    2455     hdaCodecOpenVoice(pThis, PO_INDEX, &as);
    2456 #endif
     2480
     2481    hdaCodecOpenStream(pThis, PI_INDEX, &as);
     2482    hdaCodecOpenStream(pThis, PO_INDEX, &as);
    24572483
    24582484    pThis->paNodes[1].node.au32F00_param[0xA] |= CODEC_F00_0A_44_1KHZ;
     
    24612487    Assert(pThis->paNodes);
    24622488    Assert(pThis->pfnCodecNodeReset);
     2489
    24632490    for (i = 0; i < pThis->cTotalNodes; ++i)
    2464     {
    24652491        pThis->pfnCodecNodeReset(pThis, i, &pThis->paNodes[i]);
    2466     }
     2492
    24672493#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2468     hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
    2469     hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
     2494    hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_VOLUME);
     2495    hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
    24702496#else
    24712497    hdaCodecToAudVolume(&pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
    24722498    hdaCodecToAudVolume(&pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
    2473 #endif
    2474 
    2475     /* If no host voices were created, then fallback to nul audio. */
    2476 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2477     if (!pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn))
    2478         LogRel (("HDA: pfnIsHostVoiceInOK WARNING: Unable to open PCM IN!\n"));
    2479     if (!pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut))
    2480         LogRel (("HDA: pfnIsHostVoiceOutOK WARNING: Unable to open PCM OUT!\n"));
    2481 #else
     2499
    24822500    if (!AUD_is_host_voice_in_ok(pThis->SwVoiceIn))
    24832501        LogRel (("HDA: WARNING: Unable to open PCM IN!\n"));
    24842502    if (!AUD_is_host_voice_out_ok(pThis->SwVoiceOut))
    24852503        LogRel (("HDA: WARNING: Unable to open PCM OUT!\n"));
    2486 #endif
    2487 
    2488 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2489     if (   !pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn)
    2490         && !pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut))
    2491 #else
     2504
    24922505    if (   !AUD_is_host_voice_in_ok(pThis->SwVoiceIn)
    24932506        && !AUD_is_host_voice_out_ok(pThis->SwVoiceOut))
    2494 #endif
    2495     {
    2496         /* Was not able initialize *any* voice. Select the NULL audio driver instead */
    2497 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2498         pThis->pDrv->pfnCloseIn(pThis->pDrv, pThis->SwVoiceIn);
    2499         pThis->pDrv->pfnCloseOut(pThis->pDrv, pThis->SwVoiceOut);
    2500 #else
     2507    {
    25012508        AUD_close_in(&pThis->card, pThis->SwVoiceIn);
    25022509        AUD_close_out(&pThis->card, pThis->SwVoiceOut);
    2503 #endif
     2510
    25042511        pThis->SwVoiceOut = NULL;
    25052512        pThis->SwVoiceIn = NULL;
    2506 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2507         pThis->pDrv->pfnInitNull(pThis->pDrv);
    2508 #else
     2513
    25092514        AUD_init_null ();
    2510 #endif
    25112515
    25122516        PDMDevHlpVMSetRuntimeError (pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     
    25142518                "with the consequence that no sound is audible"));
    25152519    }
    2516 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2517     else if (   !pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn)
    2518              || !pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut))
    2519 
    2520 #else
    25212520    else if (   !AUD_is_host_voice_in_ok(pThis->SwVoiceIn)
    25222521             || !AUD_is_host_voice_out_ok(pThis->SwVoiceOut))
    2523 #endif
    25242522    {
    25252523        char   szMissingVoices[128];
    25262524        size_t len = 0;
    2527  #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2528         if (!pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn))
    2529             len = RTStrPrintf (szMissingVoices, sizeof(szMissingVoices), "PCM_in");
    2530         if (!pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut))
    2531             len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out");
    2532  #else
     2525
    25332526        if (!AUD_is_host_voice_in_ok(pThis->SwVoiceIn))
    25342527            len = RTStrPrintf (szMissingVoices, sizeof(szMissingVoices), "PCM_in");
     
    25362529            len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out");
    25372530
    2538  #endif
    25392531        PDMDevHlpVMSetRuntimeError (pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    25402532            N_ ("Some audio devices (%s) could not be opened. Guest applications generating audio "
     
    25432535                "subsystem"), szMissingVoices);
    25442536    }
    2545 
    2546     return VINF_SUCCESS;
    2547 }
    2548 
     2537#endif
     2538
     2539    return VINF_SUCCESS;
     2540}
     2541
  • trunk/src/VBox/Devices/Audio/DevIchHdaCodec.h

    r50686 r53442  
    55
    66/*
    7  * Copyright (C) 2006-2013 Oracle Corporation
     7 * Copyright (C) 2006-2014 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1818#ifndef DEV_CODEC_H
    1919#define DEV_CODEC_H
    20 //#include <VBox/vmm/pdmdev.h>
     20
     21/** The ICH HDA (Intel) controller. */
     22typedef struct HDASTATE *PHDASTATE;
    2123/** The ICH HDA (Intel) codec state. */
    22 typedef struct HDACODEC HDACODEC;
    23 /** Pointer to the Intel ICH HDA codec state. */
    24 typedef HDACODEC *PHDACODEC;
    25 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    26 typedef struct PDMIAUDIOCONNECTOR * PPDMIAUDIOCONNECTOR;
    27 typedef struct PDMGSTVOICEOUT *PPDMGSTVOICEOUT;
    28 typedef struct PDMGSTVOICEIN  *PPDMGSTVOICEIN;
    29 #endif
     24typedef struct HDACODEC HDACODEC, *PHDACODEC;
     25/** The HDA host driver backend. */
     26typedef struct HDADRIVER HDADRIVER, *PHDADRIVER;
     27typedef struct PDMIAUDIOCONNECTOR *PPDMIAUDIOCONNECTOR;
     28typedef struct PDMAUDIOGSTSTRMOUT *PPDMAUDIOGSTSTRMOUT;
     29typedef struct PDMAUDIOGSTSTRMIN  *PPDMAUDIOGSTSTRMIN;
     30
    3031/**
    3132 * Verb processor method.
     
    6869} ENMSOUNDSOURCE;
    6970
    70 
    7171typedef struct HDACODEC
    7272{
     
    7676    uint8_t                 u8BSKU;
    7777    uint8_t                 u8AssemblyId;
    78 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    79     R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pDrv;
    80     /** Pointer to the attached audio driver. */
    81     R3PTRTYPE(PPDMIBASE)               pDrvBase;
    82 #endif
     78    /* List of assigned HDA drivers to this codec.
     79     * A driver only can be assigned to one codec
     80     * at a time. */
     81    RTLISTANCHOR            lstDrv;
    8382
    8483#ifndef VBOX_WITH_HDA_CODEC_EMU
     
    8988#endif
    9089    PCODECNODE              paNodes;
    91 
     90    /** Pointer to HDA state (controller) this
     91     *  codec is assigned to. */
     92    PHDASTATE               pHDAState;
     93    bool                    fInReset;
     94#ifndef VBOX_WITH_HDA_CODEC_EMU
     95    const uint8_t           cTotalNodes;
     96    const uint8_t          *au8Ports;
     97    const uint8_t          *au8Dacs;
     98    const uint8_t          *au8AdcVols;
     99    const uint8_t          *au8Adcs;
     100    const uint8_t          *au8AdcMuxs;
     101    const uint8_t          *au8Pcbeeps;
     102    const uint8_t          *au8SpdifIns;
     103    const uint8_t          *au8SpdifOuts;
     104    const uint8_t          *au8DigInPins;
     105    const uint8_t          *au8DigOutPins;
     106    const uint8_t          *au8Cds;
     107    const uint8_t          *au8VolKnobs;
     108    const uint8_t          *au8Reserveds;
     109    const uint8_t           u8AdcVolsLineIn;
     110    const uint8_t           u8DacLineOut;
     111#endif
    92112#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    93     /** PCM in */
    94     R3PTRTYPE(PPDMGSTVOICEIN)         SwVoiceIn;
    95     /** PCM out */
    96     R3PTRTYPE(PPDMGSTVOICEOUT)        SwVoiceOut;
     113    /* Callbacks to the HDA controller, mostly used for multiplexing to the various host backends. */
     114    DECLR3CALLBACKMEMBER(void, pfnCloseIn, (PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource));
     115    DECLR3CALLBACKMEMBER(void, pfnCloseOut, (PHDASTATE pThis));
     116    DECLR3CALLBACKMEMBER(int, pfnOpenIn, (PHDASTATE pThis, const char *pszName, PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg));
     117    DECLR3CALLBACKMEMBER(int, pfnOpenOut, (PHDASTATE pThis, const char *pszName, PPDMAUDIOSTREAMCFG pCfg));
     118    DECLR3CALLBACKMEMBER(int, pfnSetVolume, (PHDASTATE pThis, bool fMute, uint8_t uVolLeft, uint8_t uVolRight));
     119    /* Callbacks for host driver backends. */
     120    DECLR3CALLBACKMEMBER(void, pfnTransfer, (PHDADRIVER pDrv, ENMSOUNDSOURCE enmSource, uint32_t cbAvail));
    97121#else
    98122    QEMUSoundCard           card;
    99123    /** PCM in */
    100     SWVoiceIn               *SwVoiceIn;
     124    SWVoiceIn              *SwVoiceIn;
    101125    /** PCM out */
    102     SWVoiceOut              *SwVoiceOut;
    103 #endif
    104     void                   *pvHDAState;
    105     bool                    fInReset;
    106 #ifndef VBOX_WITH_HDA_CODEC_EMU
    107     const uint8_t           cTotalNodes;
    108     const uint8_t           *au8Ports;
    109     const uint8_t           *au8Dacs;
    110     const uint8_t           *au8AdcVols;
    111     const uint8_t           *au8Adcs;
    112     const uint8_t           *au8AdcMuxs;
    113     const uint8_t           *au8Pcbeeps;
    114     const uint8_t           *au8SpdifIns;
    115     const uint8_t           *au8SpdifOuts;
    116     const uint8_t           *au8DigInPins;
    117     const uint8_t           *au8DigOutPins;
    118     const uint8_t           *au8Cds;
    119     const uint8_t           *au8VolKnobs;
    120     const uint8_t           *au8Reserveds;
    121     const uint8_t           u8AdcVolsLineIn;
    122     const uint8_t           u8DacLineOut;
    123 #endif
    124     DECLR3CALLBACKMEMBER(int, pfnProcess, (PHDACODEC pCodec));
    125     DECLR3CALLBACKMEMBER(void, pfnTransfer, (PHDACODEC pCodec, ENMSOUNDSOURCE, int avail));
    126     /* These callbacks are set by Codec implementation. */
     126    SWVoiceOut             *SwVoiceOut;
     127    /* Callbacks for host driver backends. */
     128    DECLR3CALLBACKMEMBER(void, pfnTransfer, (PHDACODEC pCodec, ENMSOUNDSOURCE enmSource, int cbAvail));
     129#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     130    /* Callbacks by codec implementation. */
    127131    DECLR3CALLBACKMEMBER(int, pfnLookup, (PHDACODEC pThis, uint32_t verb, PPFNHDACODECVERBPROCESSOR));
    128132    DECLR3CALLBACKMEMBER(int, pfnReset, (PHDACODEC pThis));
    129133    DECLR3CALLBACKMEMBER(int, pfnCodecNodeReset, (PHDACODEC pThis, uint8_t, PCODECNODE));
    130     /* These callbacks are set by codec implementation to answer debugger requests. */
     134    /* Callbacks by codec implementation to answer debugger requests. */
    131135    DECLR3CALLBACKMEMBER(void, pfnCodecDbgListNodes, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs));
    132136    DECLR3CALLBACKMEMBER(void, pfnCodecDbgSelector, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs));
    133137} CODECState;
    134138
    135 int hdaCodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, PCFGMNODE pCfg);
     139int hdaCodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, uint16_t uLUN, PCFGMNODE pCfg);
    136140int hdaCodecDestruct(PHDACODEC pThis);
    137141int hdaCodecSaveState(PHDACODEC pThis, PSSMHANDLE pSSM);
    138142int hdaCodecLoadState(PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion);
     143#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     144int hdaCodecOpenStream(PHDACODEC pThis, PDMAUDIORECSOURCE enmRecSource, PDMAUDIOSTREAMCFG *pAudioSettings);
     145#else
    139146int hdaCodecOpenVoice(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, audsettings_t *pAudioSettings);
     147#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    140148
    141149#define HDA_SSM_VERSION   4
     
    154162# endif
    155163#endif
     164
  • trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r50686 r53442  
    3434#define LOG_GROUP LOG_GROUP_DEV_AUDIO
    3535#include <VBox/vmm/pdmdev.h>
    36 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    3736#include <VBox/vmm/pdmaudioifs.h>
    38 #endif
    3937#include <iprt/assert.h>
    4038#include <iprt/string.h>
     
    9088    /** Pointer to the device instance. */
    9189    PPDMDEVINSR3 pDevIns;
    92 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    9390    /** Pointer to the connector of the attached audio driver. */
    9491    PPDMIAUDIOCONNECTOR     pDrv;
    95 # endif
    96 #endif
    97 #ifndef VBOX
    98     qemu_irq *pic;
    99 #endif
    100 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    101     QEMUSoundCard card;
    10292#endif
    10393#ifdef VBOX /* lazy bird */
     
    119109    int fmt_signed;
    120110    int fmt_bits;
     111#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     112    PDMAUDIOFMT fmt;
     113#else
    121114    audfmt_e fmt;
     115    QEMUSoundCard card;
     116#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    122117    int dma_auto;
    123118    int block_size;
     
    154149    int bytes_per_second;
    155150    int align;
    156     int audio_free;
     151    uint32_t audio_free;
     152
    157153#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    158     PPDMGSTVOICEOUT voice;
     154    PPDMAUDIOGSTSTRMOUT pGstStrmOut;
    159155#else
    160156    SWVoiceOut *voice;
    161 #endif
    162 
    163 #ifndef VBOX
    164     QEMUTimer *aux_ts;
    165 #else
     157#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     158
    166159    PTMTIMER  pTimer;
    167160    PPDMIBASE pDrvBase;
    168161    /** LUN\#0: Base interface. */
    169162    PDMIBASE  IBase;
    170 #endif
     163
    171164    /* mixer state */
    172165    int mixer_nreg;
     
    174167} SB16State;
    175168
    176 static void SB_audio_callback (void *opaque, int free);
     169#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     170static void sb16AudioCallback(void *pvContext, uint32_t cbFree);
     171#else
     172static void sb16AudioCallback(void *pvContext, int cbFree);
     173#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    177174
    178175static int magic_of_irq (int irq)
     
    188185        return 8;
    189186    default:
    190         LogFlow(("SB16: bad irq %d\n", irq));
     187        LogFlowFunc(("bad irq %d\n", irq));
    191188        return 2;
    192189    }
     
    205202        return 10;
    206203    default:
    207         LogFlow(("SB16: bad irq magic %d\n", magic));
     204        LogFlowFunc(("bad irq magic %d\n", magic));
    208205        return -1;
    209206    }
     
    236233    s->dma_running = hold;
    237234
    238     LogFlow(("SB16: hold %d high %d dma %d\n", hold, s->use_hdma, dma));
     235    LogFlowFunc(("hold %d high %d dma %d\n", hold, s->use_hdma, dma));
    239236
    240237#ifndef VBOX
     
    253250        PDMDevHlpDMASchedule (s->pDevIns);
    254251#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    255         s->pDrv->pfnEnableOut(s->pDrv, s->voice, 1);
     252        s->pDrv->pfnEnableOut(s->pDrv, s->pGstStrmOut, true /* fEnable */);
    256253#else
    257254        AUD_set_active_out (s->voice, 1);
     
    262259        PDMDevHlpDMASetDREQ (s->pDevIns, dma, 0);
    263260#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    264         s->pDrv->pfnEnableOut(s->pDrv, s->voice, 0);
     261        s->pDrv->pfnEnableOut(s->pDrv, s->pGstStrmOut, false /* fEnable */);
    265262#else
    266263        AUD_set_active_out (s->voice, 0);
     
    291288static void continue_dma8 (SB16State *s)
    292289{
     290    if (s->freq > 0)
     291    {
     292        s->audio_free = 0;
     293
    293294#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    294     int rc;
    295 #endif
    296     if (s->freq > 0) {
    297 
    298         s->audio_free = 0;
    299 
    300 
    301 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    302         rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s, SB_audio_callback, s->freq, 1 << s->fmt_stereo,
    303                                  s->fmt, 0);
     295        PDMAUDIOSTREAMCFG as;
     296        as.uHz           = s->freq;
     297        as.cChannels     = 1 << s->fmt_stereo;
     298        as.enmFormat     = s->fmt;
     299        as.enmEndianness = PDMAUDIOHOSTENDIANESS;
     300
     301        int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out",
     302                                     sb16AudioCallback /* fnCallback */, s /* pvCallback */,
     303                                     &as,
     304                                     &s->pGstStrmOut);
     305        AssertRC(rc);
    304306#else
    305307        audsettings_t as;
     
    313315            "sb16",
    314316            s,
    315             SB_audio_callback,
     317            sb16AudioCallback,
    316318            &as
    317319            );
    318 #endif
     320#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    319321    }
    320322
     
    345347           and SecondReality/FC work
    346348
     349           r=andy Wow, actually someone who remembers Future Crew :-)
     350
    347351           Act1 sets block size via command 0x48 and it's an odd number
    348352           SR does the same with even number
     
    360364
    361365    if (s->block_size & s->align) {
    362         LogFlow(("SB16: warning: misaligned block size %d, alignment %d\n",
     366        LogFlowFunc(("warning: misaligned block size %d, alignment %d\n",
    363367               s->block_size, s->align + 1));
    364368    }
    365369
    366     LogFlow(("SB16: freq %d, stereo %d, sign %d, bits %d, "
     370    LogFlowFunc(("freq %d, stereo %d, sign %d, bits %d, "
    367371            "dma %d, auto %d, fifo %d, high %d\n",
    368372            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
     
    412416    }
    413417
    414     LogFlow(("SB16: freq %d, stereo %d, sign %d, bits %d, "
     418    LogFlowFunc(("freq %d, stereo %d, sign %d, bits %d, "
    415419            "dma %d, auto %d, fifo %d, high %d\n",
    416420            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
     
    440444    s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
    441445    if (s->block_size & s->align) {
    442         LogFlow(("SB16: warning: misaligned block size %d, alignment %d\n",
     446        LogFlowFunc(("warning: misaligned block size %d, alignment %d\n",
    443447               s->block_size, s->align + 1));
    444448    }
    445449
    446     if (s->freq) {
    447 
     450    if (s->freq)
     451    {
    448452        s->audio_free = 0;
    449453
    450 
    451454#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    452     int rc;
    453         rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s,SB_audio_callback, s->freq, 1 << s->fmt_stereo, s->fmt, 0);
     455        PDMAUDIOSTREAMCFG as;
     456        as.uHz           = s->freq;
     457        as.cChannels     = 1 << s->fmt_stereo;
     458        as.enmFormat     = s->fmt;
     459        as.enmEndianness = PDMAUDIOHOSTENDIANESS;
     460
     461        int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out",
     462                                     sb16AudioCallback /* fnCallback */, s /* pvCallback */,
     463                                     &as,
     464                                     &s->pGstStrmOut);
     465        AssertRC(rc);
    454466#else
    455467        audsettings_t as;
     
    463475            "sb16",
    464476            s,
    465             SB_audio_callback,
     477            sb16AudioCallback,
    466478            &as
    467479            );
    468 #endif
     480#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    469481    }
    470482
     
    475487static inline void dsp_out_data (SB16State *s, uint8_t val)
    476488{
    477     LogFlow(("SB16: outdata %#x\n", val));
     489    LogFlowFunc(("outdata %#x\n", val));
    478490    if ((size_t) s->out_data_len < sizeof (s->out_data)) {
    479491        s->out_data[s->out_data_len++] = val;
     
    487499    }
    488500    else {
    489         LogFlow(("SB16: buffer underflow\n"));
     501        LogFlowFunc(("buffer underflow\n"));
    490502        return 0;
    491503    }
     
    494506static void command (SB16State *s, uint8_t cmd)
    495507{
    496     LogFlow(("SB16: command %#x\n", cmd));
     508    LogFlowFunc(("command %#x\n", cmd));
    497509
    498510    if (cmd > 0xaf && cmd < 0xd0) {
    499511        if (cmd & 8) {
    500             LogFlow(("SB16: ADC not yet supported (command %#x)\n", cmd));
     512            LogFlowFunc(("ADC not yet supported (command %#x)\n", cmd));
    501513        }
    502514
     
    506518            break;
    507519        default:
    508             LogFlow(("SB16: %#x wrong bits\n", cmd));
     520            LogFlowFunc(("%#x wrong bits\n", cmd));
    509521        }
    510522        s->needed_bytes = 3;
     
    560572
    561573        case 0x35:
    562             LogFlow(("SB16: 0x35 - MIDI command not implemented\n"));
     574            LogFlowFunc(("0x35 - MIDI command not implemented\n"));
    563575            break;
    564576
     
    594606        case 0x74:
    595607            s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
    596             LogFlow(("SB16: 0x75 - DMA DAC, 4-bit ADPCM not implemented\n"));
     608            LogFlowFunc(("0x75 - DMA DAC, 4-bit ADPCM not implemented\n"));
    597609            break;
    598610
    599611        case 0x75:              /* DMA DAC, 4-bit ADPCM Reference */
    600612            s->needed_bytes = 2;
    601             LogFlow(("SB16: 0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n"));
     613            LogFlowFunc(("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n"));
    602614            break;
    603615
    604616        case 0x76:              /* DMA DAC, 2.6-bit ADPCM */
    605617            s->needed_bytes = 2;
    606             LogFlow(("SB16: 0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n"));
     618            LogFlowFunc(("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n"));
    607619            break;
    608620
    609621        case 0x77:              /* DMA DAC, 2.6-bit ADPCM Reference */
    610622            s->needed_bytes = 2;
    611             LogFlow(("SB16: 0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n"));
     623            LogFlowFunc(("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n"));
    612624            break;
    613625
    614626        case 0x7d:
    615             LogFlow(("SB16: 0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n"));
    616             LogFlow(("SB16: not implemented\n"));
     627            LogFlowFunc(("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n"));
     628            LogFlowFunc(("not implemented\n"));
    617629            break;
    618630
    619631        case 0x7f:
    620             LogFlow(("SB16: 0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"));
    621             LogFlow(("SB16: not implemented\n"));
     632            LogFlowFunc(("0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"));
     633            LogFlowFunc(("not implemented\n"));
    622634            break;
    623635
     
    691703
    692704        case 0xe7:
    693             LogFlow(("SB16: Attempt to probe for ESS (0xe7)?\n"));
     705            LogFlowFunc(("Attempt to probe for ESS (0xe7)?\n"));
    694706            break;
    695707
     
    722734
    723735        default:
    724             LogFlow(("SB16: Unrecognized command %#x\n", cmd));
     736            LogFlowFunc(("Unrecognized command %#x\n", cmd));
    725737            break;
    726738        }
     
    741753
    742754 warn:
    743     LogFlow(("SB16: warning: command %#x,%d is not truly understood yet\n",
     755    LogFlowFunc(("warning: command %#x,%d is not truly understood yet\n",
    744756           cmd, s->needed_bytes));
    745757    goto exit;
     
    764776{
    765777    int d0, d1, d2;
    766     LogFlow(("SB16: complete command %#x, in_index %d, needed_bytes %d\n",
     778    LogFlowFunc(("complete command %#x, in_index %d, needed_bytes %d\n",
    767779            s->cmd, s->in_index, s->needed_bytes));
    768780
     
    773785
    774786        if (s->cmd & 8) {
    775             LogFlow(("SB16: ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
     787            LogFlowFunc(("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
    776788                   s->cmd, d0, d1, d2));
    777789        }
    778790        else {
    779             LogFlow(("SB16: cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
     791            LogFlowFunc(("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
    780792                    s->cmd, d0, d1, d2));
    781793            dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
     
    788800            s->csp_reg83r = 0;
    789801            s->csp_reg83w = 0;
    790             LogFlow(("SB16: CSP command 0x04: mode=%#x\n", s->csp_mode));
     802            LogFlowFunc(("CSP command 0x04: mode=%#x\n", s->csp_mode));
    791803            break;
    792804
     
    794806            s->csp_param = dsp_get_data (s);
    795807            s->csp_value = dsp_get_data (s);
    796             LogFlow(("SB16: CSP command 0x05: param=%#x value=%#x\n",
     808            LogFlowFunc(("CSP command 0x05: param=%#x value=%#x\n",
    797809                    s->csp_param,
    798810                    s->csp_value));
     
    802814            d0 = dsp_get_data (s);
    803815            d1 = dsp_get_data (s);
    804             LogFlow(("SB16: write CSP register %d <- %#x\n", d1, d0));
     816            LogFlowFunc(("write CSP register %d <- %#x\n", d1, d0));
    805817            if (d1 == 0x83) {
    806                 LogFlow(("SB16: 0x83[%d] <- %#x\n", s->csp_reg83r, d0));
     818                LogFlowFunc(("0x83[%d] <- %#x\n", s->csp_reg83r, d0));
    807819                s->csp_reg83[s->csp_reg83r % 4] = d0;
    808820                s->csp_reg83r += 1;
     
    815827        case 0x0f:
    816828            d0 = dsp_get_data (s);
    817             LogFlow(("SB16: read CSP register %#x -> %#x, mode=%#x\n",
     829            LogFlowFunc(("read CSP register %#x -> %#x, mode=%#x\n",
    818830                    d0, s->csp_regs[d0], s->csp_mode));
    819831            if (d0 == 0x83) {
    820                 LogFlow(("SB16: 0x83[%d] -> %#x\n",
     832                LogFlowFunc(("0x83[%d] -> %#x\n",
    821833                        s->csp_reg83w,
    822834                        s->csp_reg83[s->csp_reg83w % 4]));
     
    831843        case 0x10:
    832844            d0 = dsp_get_data (s);
    833             LogFlow(("SB16: cmd 0x10 d0=%#x\n", d0));
     845            LogFlowFunc(("cmd 0x10 d0=%#x\n", d0));
    834846            break;
    835847
     
    840852        case 0x40:
    841853            s->time_const = dsp_get_data (s);
    842             LogFlow(("SB16: set time const %d\n", s->time_const));
     854            LogFlowFunc(("set time const %d\n", s->time_const));
    843855            break;
    844856
    845857        case 0x42:              /* FT2 sets output freq with this, go figure */
    846858#if 0
    847             dolog ("cmd 0x42 might not do what it think it should\n");
     859            LogFlowFunc(("cmd 0x42 might not do what it think it should\n"));
    848860#endif
    849861        case 0x41:
    850862            s->freq = dsp_get_hilo (s);
    851             LogFlow(("SB16: set freq %d\n", s->freq));
     863            LogFlowFunc(("set freq %d\n", s->freq));
    852864            break;
    853865
    854866        case 0x48:
    855867            s->block_size = dsp_get_lohi (s) + 1;
    856             LogFlow(("SB16: set dma block len %d\n", s->block_size));
     868            LogFlowFunc(("set dma block len %d\n", s->block_size));
    857869            break;
    858870
     
    885897                    }
    886898                }
    887                 LogFlow(("SB16: mix silence %d %d %" PRId64 "\n", samples, bytes, ticks));
     899                LogFlowFunc(("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks));
    888900#else  /* VBOX */
    889901                ticks = (bytes * TMTimerGetFreq(s->pTimer)) / freq;
     
    892904                else
    893905                    TMTimerSet(s->pTimer, TMTimerGet(s->pTimer) + ticks);
    894                 LogFlow(("SB16: mix silence %d %d % %RU64\n", samples, bytes, ticks));
     906                LogFlowFunc(("mix silence %d %d % %RU64\n", samples, bytes, ticks));
    895907#endif /* VBOX */
    896908            }
     
    900912            d0 = dsp_get_data (s);
    901913            s->out_data_len = 0;
    902             LogFlow(("SB16: E0 data = %#x\n", d0));
     914            LogFlowFunc(("E0 data = %#x\n", d0));
    903915            dsp_out_data (s, ~d0);
    904916            break;
     
    915927        case 0xf9:
    916928            d0 = dsp_get_data (s);
    917             LogFlow(("SB16: command 0xf9 with %#x\n", d0));
     929            LogFlowFunc(("command 0xf9 with %#x\n", d0));
    918930            switch (d0) {
    919931            case 0x0e:
     
    936948
    937949        default:
    938             LogFlow(("SB16: complete: unrecognized command %#x\n", s->cmd));
     950            LogFlowFunc(("complete: unrecognized command %#x\n", s->cmd));
    939951            return;
    940952        }
     
    948960static void legacy_reset (SB16State *s)
    949961{
    950 
    951962    s->freq = 11025;
    952963    s->fmt_signed = 0;
     
    955966
    956967#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    957     int rc;
    958     rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s, SB_audio_callback, 11025, 1, AUD_FMT_U8, 0);
     968    PDMAUDIOSTREAMCFG as;
     969    as.uHz           = s->freq;
     970    as.cChannels     = 1;
     971    as.enmFormat     = AUD_FMT_U8;
     972    as.enmEndianness = PDMAUDIOHOSTENDIANESS;
     973
     974    int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out",
     975                                 sb16AudioCallback /* fnCallback */, s /* pvContext */,
     976                                 &as,
     977                                 &s->pGstStrmOut);
     978    AssertRC(rc);
    959979#else
    960980    audsettings_t as;
     
    968988        "sb16",
    969989        s,
    970         SB_audio_callback,
     990        sb16AudioCallback,
    971991        &as
    972992        );
    973 
    974 #endif
     993#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     994
    975995    /* Not sure about that... */
    976996    /* AUD_set_active_out (s->voice, 1); */
     
    10161036    int iport = nport - s->port;
    10171037
    1018     LogFlow(("SB16: write %#x <- %#x\n", nport, val));
     1038    LogFlowFunc(("write %#x <- %#x\n", nport, val));
    10191039    switch (iport) {
    10201040    case 0x06:
     
    10771097        else {
    10781098            if (s->in_index == sizeof (s->in2_data)) {
    1079                 LogFlow(("SB16: in data overrun\n"));
     1099                LogFlowFunc(("in data overrun\n"));
    10801100            }
    10811101            else {
     
    10931113
    10941114    default:
    1095         LogFlow(("SB16: nport=%#x, val=%#x)\n", nport, val));
     1115        LogFlowFunc(("nport=%#x, val=%#x)\n", nport, val));
    10961116        break;
    10971117    }
     
    11251145        else {
    11261146            if (s->cmd != -1) {
    1127                 LogFlow(("SB16: empty output buffer for command %#x\n",
     1147                LogFlowFunc(("empty output buffer for command %#x\n",
    11281148                       s->cmd));
    11291149            }
     
    11381158
    11391159    case 0x0d:                  /* timer interrupt clear */
    1140         /* dolog ("timer interrupt clear\n"); */
     1160        /* LogFlowFunc(("timer interrupt clear\n")); */
    11411161        retval = 0;
    11421162        break;
     
    11731193
    11741194    if (!ack) {
    1175         LogFlow(("SB16: read %#x -> %#x\n", nport, retval));
     1195        LogFlowFunc(("read %#x -> %#x\n", nport, retval));
    11761196    }
    11771197
     
    11841204
    11851205 error:
    1186     LogFlow(("SB16: warning: dsp_read %#x error\n", nport));
     1206    LogFlowFunc(("warning: dsp_read %#x error\n", nport));
    11871207#ifndef VBOX
    11881208    return 0xff;
     
    12321252#endif
    12331253}
     1254
    12341255#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1235 uint32_t popcount (uint32_t u)
     1256uint32_t popcount (uint32_t u) /** @todo r=andy WTF? */
    12361257{
    12371258    u = ((u&0x55555555) + ((u>>1)&0x55555555));
     
    12451266uint32_t lsbindex (uint32_t u)
    12461267{
    1247     return popcount ((u&-u)-1);
     1268    return popcount ((u&-u)-1); /** @todo r=andy Un/signed mismatch? */
    12481269}
    12491270#endif
     
    12561277
    12571278    (void) nport;
    1258     LogFlow(("SB16: mixer_write [%#x] <- %#x\n", s->mixer_nreg, val));
     1279    LogFlowFunc(("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val));
    12591280
    12601281    switch (s->mixer_nreg) {
     
    13071328        {
    13081329            int irq = irq_of_magic (val);
    1309             LogFlow(("SB16: setting irq to %d (val=%#x)\n", irq, val));
     1330            LogFlowFunc(("setting irq to %d (val=%#x)\n", irq, val));
    13101331            if (irq > 0) {
    13111332                s->irq = irq;
     
    13341355
    13351356    case 0x82:
    1336         LogFlow(("SB16: attempt to write into IRQ status register (val=%#x)\n",
     1357        LogFlowFunc(("attempt to write into IRQ status register (val=%#x)\n",
    13371358               val));
    13381359#ifdef VBOX
     
    13421363    default:
    13431364        if (s->mixer_nreg >= 0x80) {
    1344             LogFlow(("SB16: attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val));
     1365            LogFlowFunc(("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val));
    13451366        }
    13461367        break;
     
    13561377        uint8_t lvol = s->mixer_regs[0x30];
    13571378        uint8_t rvol = s->mixer_regs[0x31];
     1379
    13581380#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1359         /*@todo not passinga audmixer_Ctl values as its not used in DrvAudio.c */
    1360         s->pDrv->pfnSetVolume(s->pDrv, &mute, &lvol, &rvol);
     1381        s->pDrv->pfnSetVolume(s->pDrv, RT_BOOL(mute), lvol, rvol);
    13611382#else
    13621383        AUD_set_volume(AUD_MIXER_VOLUME, &mute, &lvol, &rvol);
    1363 #endif
     1384#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    13641385    }
    13651386    /* Update the voice (PCM) volume. */
     
    13691390        uint8_t lvol = s->mixer_regs[0x32];
    13701391        uint8_t rvol = s->mixer_regs[0x33];
     1392
    13711393#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1372         s->pDrv->pfnSetVolume(s->pDrv, &mute, &lvol, &rvol);
     1394        s->pDrv->pfnSetVolume(s->pDrv, RT_BOOL(mute), lvol, rvol);
    13731395#else
    13741396        AUD_set_volume(AUD_MIXER_PCM, &mute, &lvol, &rvol);
    1375 #endif
     1397#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    13761398    }
    13771399#endif /* VBOX */
     
    14221444#ifndef DEBUG_SB16_MOST
    14231445    if (s->mixer_nreg != 0x82) {
    1424         LogFlow(("SB16: mixer_read[%#x] -> %#x\n",
     1446        LogFlowFunc(("mixer_read[%#x] -> %#x\n",
    14251447                s->mixer_nreg, s->mixer_regs[s->mixer_nreg]));
    14261448    }
    14271449#else
    1428     LogFlow(("SB16: mixer_read[%#x] -> %#x\n",
     1450    LogFlowFunc(("mixer_read[%#x] -> %#x\n",
    14291451            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]));
    14301452#endif
     
    14411463{
    14421464    int temp, net;
    1443     uint8_t tmpbuf[4096];
     1465    uint8_t tmpbuf[_4K];
    14441466
    14451467    temp = len;
    14461468    net = 0;
    14471469
    1448     while (temp) {
     1470    while (temp)
     1471    {
    14491472        int left = dma_len - dma_pos;
    14501473#ifndef VBOX
     1474        size_t to_copy;
    14511475        int copied;
     1476#else
    14521477        size_t to_copy;
    1453 #else
    14541478        uint32_t copied;
    1455         uint32_t to_copy;
    1456 #endif
    1457 
    1458         to_copy = audio_MIN (temp, left);
    1459         if (to_copy > sizeof (tmpbuf)) {
    1460             to_copy = sizeof (tmpbuf);
    1461         }
     1479#endif
     1480
     1481        to_copy = RT_MIN(temp, left);
     1482        if (to_copy > sizeof(tmpbuf))
     1483            to_copy = sizeof(tmpbuf);
    14621484
    14631485#ifndef VBOX
     
    14701492
    14711493#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1472         copied = s->pDrv->pfnWrite(s->pDrv, s->voice, tmpbuf, copied);
     1494        rc = s->pDrv->pfnWrite(s->pDrv, s->pGstStrmOut, tmpbuf, to_copy, &copied);
     1495        if (RT_FAILURE(rc))
     1496            break;
    14731497#else
    14741498        copied = AUD_write (s->voice, tmpbuf, copied);
    1475 #endif
     1499#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    14761500
    14771501        temp -= copied;
     
    14791503        net += copied;
    14801504
    1481         if (!copied) {
    1482             break;
    1483         }
     1505        if (!copied)
     1506            break;
    14841507    }
    14851508
     
    14971520
    14981521    if (s->block_size <= 0) {
    1499         LogFlow(("SB16: invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
     1522        LogFlowFunc(("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
    15001523               s->block_size, nchan, dma_pos, dma_len));
    15011524        return dma_pos;
     
    15061529    }
    15071530
     1531#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1532    if (s->pGstStrmOut) {
     1533#else
    15081534    if (s->voice) {
     1535#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    15091536        free = s->audio_free & ~s->align;
    15101537        if ((free <= 0) || !dma_len) {
     
    15201547
    15211548#ifdef DEBUG_SB16_MOST
    1522     LogFlow(("SB16: pos:%06d %d till:%d len:%d\n",
     1549    LogFlowFunc(("pos:%06d %d till:%d len:%d\n",
    15231550           dma_pos, free, till, dma_len));
    15241551#endif
     
    15521579
    15531580#ifdef DEBUG_SB16_MOST
    1554     LogFlow(("SB16: pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
     1581    LogFlowFunc(("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
    15551582            dma_pos, free, dma_len, s->left_till_irq, copy, written,
    15561583            s->block_size));
     
    15641591}
    15651592
    1566 static void SB_audio_callback (void *opaque, int free)
    1567 {
    1568     SB16State *s = (SB16State*)opaque;
    1569     s->audio_free = free;
     1593#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1594static void sb16AudioCallback(void *pvContext, uint32_t cbFree)
     1595#else
     1596static void sb16AudioCallback(void *pvContext, int cbFree)
     1597#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1598{
     1599    SB16State *pState = (SB16State*)pvContext;
     1600    AssertPtrReturnVoid(pState);
     1601    pState->audio_free = cbFree;
    15701602#ifdef VBOX
    15711603    /* New space available, see if we can transfer more. There is no cyclic DMA timer in VBox. */
    1572     PDMDevHlpDMASchedule (s->pDevIns);
     1604    PDMDevHlpDMASchedule(pState->pDevIns);
    15731605#endif
    15741606}
     
    16911723    qemu_get_buffer (f, s->mixer_regs, 256);
    16921724
    1693     if (s->voice) {
    16941725#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1695         s->pDrv->pfnCloseOut(s->pDrv, s->voice);
    1696 #else
    1697         AUD_close_out (&s->card, s->voice);
    1698 #endif
    1699         s->voice = NULL;
    1700     }
    1701 
    1702     if (s->dma_running) {
    1703         if (s->freq) {
    1704 
     1726    if (s->pGstStrmOut)
     1727    {
     1728        s->pDrv->pfnCloseOut(s->pDrv, s->pGstStrmOut);
     1729        s->pGstStrmOut = NULL;
     1730    }
     1731#else
     1732    AUD_close_out (&s->card, s->voice);
     1733    s->voice = NULL;
     1734#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1735
     1736    if (s->dma_running)
     1737    {
     1738        if (s->freq)
     1739        {
    17051740            s->audio_free = 0;
    17061741
    17071742#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1708             int rc;
    1709             rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s, SB_audio_callback, s->freq, 1 << s->fmt_stereo, s->fmt, 0);
     1743            PDMAUDIOSTREAMCFG streamCfg;
     1744            streamCfg.uHz           = s->freq;
     1745            streamCfg.cChannels     = 1 << s->fmt_stereo;
     1746            streamCfg.enmFormat     = s->fmt;
     1747            streamCfg.enmEndianness = PDMAUDIOHOSTENDIANESS;
     1748
     1749            int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out",
     1750                                         sb16AudioCallback /* fnCallback */, s /* pvContext */,
     1751                                         &streamCfg,
     1752                                         &s->pGstStrmOut);
     1753            AssertRC(rc);
    17101754#else
    17111755            audsettings_t as;
     
    17191763                "sb16",
    17201764                s,
    1721                 SB_audio_callback,
     1765                sb16AudioCallback,
    17221766                &as
    17231767                );
    1724 #endif
    1725         }
    1726 
    1727         control (s, 1);
    1728         speaker (s, s->speaker);
     1768#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1769        }
     1770
     1771        control(s, 1);
     1772        speaker(s, s->speaker);
    17291773    }
    17301774
     
    17431787
    17441788    if (!audio) {
    1745         LogFlow(("SB16: No audio state\n"));
     1789        LogFlowFunc(("No audio state\n"));
    17461790        return -1;
    17471791    }
     
    17491793    s = qemu_mallocz (sizeof (*s));
    17501794    if (!s) {
    1751         LogFlow(("SB16: Could not allocate memory for SB16 (%zu bytes)\n",
    1752                sizeof (*s)));
     1795        LogFlowFunc(("Could not allocate memory for SB16 (%zu bytes)\n",
     1796               sizeof (*s));
    17531797        return -1;
    17541798    }
     
    17721816    s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
    17731817    if (!s->aux_ts) {
    1774         LogFlow(("SB16: warning: Could not create auxiliary timer\n"));
     1818        LogFlowFunc(("warning: Could not create auxiliary timer\n"));
    17751819    }
    17761820
     
    17931837
    17941838    register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
    1795     AUD_register_card (audio, "sb16");
     1839    AUD_register_card (audio, "sb16", &s->card);
    17961840    return 0;
    17971841}
     
    18771921}
    18781922
     1923/**
     1924 * @interface_method_impl{PDMDEVREG,pfnDestruct}
     1925 */
     1926static DECLCALLBACK(int) sb16Destruct(PPDMDEVINS pDevIns)
     1927{
     1928    SB16State *pThis = PDMINS_2_DATA(pDevIns, SB16State *);
     1929
     1930    return VINF_SUCCESS;
     1931}
     1932
    18791933static DECLCALLBACK(int) sb16Construct (PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
    18801934{
     
    19922046    if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    19932047#endif
    1994         Log(("ac97: No attached driver!\n"));
     2048        LogFunc(("No attached driver!\n"));
    19952049    else if (RT_FAILURE(rc))
    19962050    {
     
    19992053    }
    20002054
     2055    legacy_reset(s);
     2056
    20012057#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2002      s->pDrv->pfnRegisterCard(s->pDrv, "sb16");
    2003 #else
    2004     AUD_register_card("sb16", &s->card);
    2005 #endif
    2006     legacy_reset(s);
    2007 
    2008 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2009     if (!s->pDrv->pfnIsHostVoiceOutOK(s->pDrv,s->voice))
    2010 #else
    2011     if (!AUD_is_host_voice_out_ok(s->voice))
    2012 #endif
     2058    if (!s->pDrv->pfnIsOutputOK(s->pDrv,s->pGstStrmOut))
    20132059    {
    2014         LogRel (("SB16: WARNING: Unable to open PCM OUT!\n"));
    2015 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2016         s->pDrv->pfnCloseOut(s->pDrv, s->voice );
    2017 #else
    2018         AUD_close_out (&s->card, s->voice);
    2019 #endif
    2020         s->voice = NULL;
    2021 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2060        LogRel(("SB16: WARNING: Unable to open PCM OUT!\n"));
     2061        s->pDrv->pfnCloseOut(s->pDrv, s->pGstStrmOut );
     2062        s->pGstStrmOut = NULL;
     2063
    20222064        s->pDrv->pfnInitNull(s->pDrv);
    2023 #else
    2024         AUD_init_null();
    2025 #endif
     2065
    20262066        PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    20272067            N_("No audio devices could be opened. Selecting the NULL audio backend "
    20282068               "with the consequence that no sound is audible"));
    20292069    }
     2070#else
     2071    AUD_register_card("sb16", &s->card);
     2072
     2073    if (!AUD_is_host_voice_out_ok(s->voice))
     2074    {
     2075        LogRel (("SB16: WARNING: Unable to open PCM OUT!\n"));
     2076        AUD_close_out (&s->card, s->voice);
     2077        s->voice = NULL;
     2078
     2079        AUD_init_null();
     2080
     2081        PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     2082            N_("No audio devices could be opened. Selecting the NULL audio backend "
     2083               "with the consequence that no sound is audible"));
     2084    }
     2085#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     2086
    20302087    return VINF_SUCCESS;
    20312088}
     
    20542111    sb16Construct,
    20552112    /* pfnDestruct */
    2056     NULL,
     2113    sb16Destruct,
    20572114    /* pfnRelocate */
    20582115    NULL,
  • trunk/src/VBox/Devices/Makefile.kmk

    r53378 r53442  
    2626# Include sub-makefiles.
    2727include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk
     28ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     29 include $(PATH_SUB_CURRENT)/Audio/testcase/Makefile.kmk
     30endif
    2831include $(PATH_SUB_CURRENT)/Input/testcase/Makefile.kmk
    2932if defined(VBOX_WITH_INTEL_PXE) || defined(VBOX_ONLY_EXTPACKS)
     
    165168        Parallel/DevParallel.cpp \
    166169        \
    167         Audio/mixeng.c \
    168170        Input/DrvKeyboardQueue.cpp \
    169171        Input/DrvMouseQueue.cpp \
     
    509511
    510512 ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    511    VBoxDD_DEFS         +=VBOX_WITH_PDM_AUDIO_DRIVER
    512  endif
    513  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    514    VBoxDD_SOURCES += Audio/DrvAudio.c \
    515          Audio/DrvAudioUtil.c \
    516          Audio/DrvHostNullAudio.c
    517  else
    518    VBoxDD_SOURCES += Audio/audio.c \
     513  VBoxDD_DEFS            += VBOX_WITH_PDM_AUDIO_DRIVER
     514  VBoxDD_SOURCES         += \
     515        Audio/AudioMixBuffer.cpp   \
     516        Audio/AudioMixer.cpp       \
     517        Audio/DrvAudio.cpp         \
     518        Audio/DrvAudioCommon.cpp   \
     519        Audio/DrvHostNullAudio.cpp
     520
     521  ## @todo Darwin CoreAudio driver missing!
     522
     523  ifeq ($(KBUILD_TARGET),win)
     524   VBoxDD_SOURCES += \
     525        Audio/DrvHostDSound.cpp
     526   VBoxDD_LIBS    += \
     527        $(PATH_SDK_$(VBOX_WINDDK)_LIB)/dsound.lib
     528  endif
     529
     530  ifeq ($(KBUILD_TARGET),linux)
     531   VBoxDD_SOURCES  += \
     532                Audio/DrvHostOssAudio.cpp
     533   ifdef VBOX_WITH_PULSE
     534    VBoxDD_DEFS    += VBOX_WITH_PULSE
     535    VBoxDD_SOURCES += \
     536        Audio/DrvHostPulseAudio.cpp \
     537        Audio/pulse_stubs.c
     538   endif
     539
     540   ifdef VBOX_WITH_ALSA
     541    VBoxDD_DEFS.linux    += VBOX_WITH_ALSA
     542    VBoxDD_SOURCES.linux += \
     543        Audio/DrvHostAlsaAudio.cpp \
     544        Audio/alsa_stubs.c
     545   endif
     546  endif
     547
     548  ifeq ($(KBUILD_TARGET),freebsd)
     549   VBoxDD_SOURCES  += \
     550                Audio/DrvHostOssAudio.cpp
     551   ifdef VBOX_WITH_PULSE
     552    VBoxDD_DEFS    += VBOX_WITH_PULSE
     553    VBoxDD_SOURCES += \
     554        Audio/DrvHostPulseAudio.cpp \
     555        Audio/pulse_stubs.c
     556   endif
     557  endif
     558
     559  ifeq ($(KBUILD_TARGET),solaris)
     560   VBoxDD_SOURCES += \
     561        Audio/DrvHostSolAudio.cpp
     562   ifdef VBOX_WITH_SOLARIS_OSS
     563    VBoxDD_SOURCES += Audio/DrvHostOSSAudio.cpp
     564    VBoxDD_DEFS    += VBOX_WITH_SOLARIS_OSS
     565   endif
     566  endif
     567
     568 else # !VBOX_WITH_PDM_AUDIO_DRIVER
     569
     570  VBoxDD_SOURCES += \
     571         Audio/audio.c \
    519572         Audio/audiosniffer.c \
    520573         Audio/noaudio.c \
    521          Audio/filteraudio.c
    522  endif
    523 
    524  ifdef VBOX_WITH_ALSA
    525   VBoxDD_DEFS.linux     += VBOX_WITH_ALSA
    526   ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    527     VBoxDD_DEFS.linux     += VBOX_WITH_WITH_PDM_AUDIO_DRIVER
    528     VBoxDD_SOURCES.linux  += \
    529           Audio/DrvHostAlsaAudio.c \
    530       Audio/alsa_stubs.c
    531   else
    532     VBoxDD_SOURCES.linux  += \
     574         Audio/filteraudio.c \
     575         Audio/mixeng.c
     576
     577  ifeq ($(KBUILD_TARGET),win)
     578   VBoxDD_SOURCES += \
     579        Audio/dsoundaudio.c
     580  endif
     581
     582  VBoxDD_SOURCES.darwin  += \
     583        Audio/coreaudio.c
     584
     585  ifeq ($(KBUILD_TARGET),solaris)
     586   VBoxDD_SOURCES += \
     587        Audio/solaudio.c
     588   ifdef VBOX_WITH_SOLARIS_OSS
     589    VBoxDD_DEFS    += VBOX_WITH_SOLARIS_OSS
     590    VBoxDD_SOURCES += \
     591        Audio/ossaudio.c
     592   endif
     593  endif
     594
     595  ifeq ($(KBUILD_TARGET),linux)
     596   VBoxDD_SOURCES += \
     597          Audio/ossaudio.c
     598   ifdef VBOX_WITH_PULSE
     599    VBoxDD_DEFS    += VBOX_WITH_PULSE
     600    VBoxDD_SOURCES += \
     601          Audio/pulseaudio.c \
     602          Audio/pulse_stubs.c
     603   endif
     604   ifdef VBOX_WITH_ALSA
     605    VBoxDD_DEFS    += VBOX_WITH_ALSA
     606    VBoxDD_SOURCES += \
    533607          Audio/alsaaudio.c \
    534608          Audio/alsa_stubs.c
    535   endif
    536  endif
    537 
    538  ifdef VBOX_WITH_PULSE
    539   VBoxDD_DEFS.linux     += VBOX_WITH_PULSE
    540   ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    541     VBoxDD_DEFS.linux     += VBOX_WITH_PDM_AUDIO_DRIVER
    542     VBoxDD_SOURCES.linux  += \
    543           Audio/DrvHostPulseAudio.c \
    544       Audio/pulse_stubs.c
    545   else
    546     VBoxDD_SOURCES.linux  += \
     609   endif
     610  endif
     611
     612  ifeq ($(KBUILD_TARGET),freebsd)
     613   VBoxDD_SOURCES += \
     614          Audio/ossaudio.c
     615   ifdef VBOX_WITH_PULSE
     616    VBoxDD_DEFS    += VBOX_WITH_PULSE
     617    VBoxDD_SOURCES += \
    547618          Audio/pulseaudio.c \
    548619          Audio/pulse_stubs.c
    549   endif
    550   VBoxDD_DEFS.freebsd   += VBOX_WITH_PULSE
    551   ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    552     VBoxDD_SOURCES.freebsd+= \
    553           Audio/DrvHostPulseAudio.c \
    554           Audio/pulse_stubs.c
    555   else
    556     VBoxDD_SOURCES.freebsd+= \
    557           Audio/pulseaudio.c \
    558           Audio/pulse_stubs.c
    559   endif
    560  endif
    561 
     620   endif
     621  endif
     622
     623  ifeq ($(KBUILD_TARGET),solaris)
     624   VBoxDD_SOURCES += \
     625        Audio/solaudio.c
     626   ifdef VBOX_WITH_SOLARIS_OSS
     627    VBoxDD_SOURCES += Audio/ossaudio.c
     628    VBoxDD_DEFS    += VBOX_WITH_SOLARIS_OSS
     629   endif
     630  endif
     631
     632 endif # VBOX_WITH_PDM_AUDIO_DRIVER
    562633
    563634 # --- WARNING! SLIRP MESS AHEAD! ;-) ---
     
    673744 ifeq ($(KBUILD_TARGET),darwin)
    674745  VBoxDD_SOURCES        := \
    675         $(filter-out Storage/DrvHostRaw% Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \
    676         Audio/coreaudio.c
     746        $(filter-out Storage/DrvHostRaw% Storage/DrvHostFloppy%, $(VBoxDD_SOURCES))
    677747  VBoxDD_SOURCES.darwin += \
    678748        Serial/DrvHostSerial.cpp
     
    680750
    681751 ifeq ($(KBUILD_TARGET),freebsd)
    682   ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    683     VBoxDD_SOURCES        := \
    684           $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \
    685           Audio/DrvHostOssAudio.c \
    686           Serial/DrvHostSerial.cpp
    687     VBoxDD_SOURCES.freebsd += \
    688           Network/DrvTAP.cpp
    689   else
    690     VBoxDD_SOURCES        := \
    691           $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \
    692           Audio/ossaudio.c \
    693           Serial/DrvHostSerial.cpp
    694     VBoxDD_SOURCES.freebsd += \
    695           Network/DrvTAP.cpp
    696   endif
     752  VBoxDD_SOURCES        := \
     753                $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES))
     754                Serial/DrvHostSerial.cpp
     755  VBoxDD_SOURCES.freebsd += \
     756                Network/DrvTAP.cpp
    697757 endif # freebsd
    698758
    699  VBoxDD_SOURCES.linux  += \
     759 VBoxDD_SOURCES.linux   += \
    700760        Network/DrvTAP.cpp \
    701761        Parallel/DrvHostParallel.cpp \
    702762        Serial/DrvHostSerial.cpp
    703763
    704  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    705   VBoxDD_SOURCES.linux  += \
    706     Audio/DrvHostOssAudio.c
    707  else
    708    VBoxDD_SOURCES.linux  += \
    709          Audio/ossaudio.c
    710  endif
    711 
    712764 ifeq ($(KBUILD_TARGET),os2)
    713765 VBoxDD_SOURCES        := $(filter-out Storage/DrvHost%, $(VBoxDD_SOURCES))
     
    715767
    716768 ifeq ($(KBUILD_TARGET),solaris)
    717   VBoxDD_SOURCES        := $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES))
    718   VBoxDD_SOURCES.solaris += \
     769  VBoxDD_SOURCES          := $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES))
     770  VBoxDD_SOURCES.solaris  += \
    719771        Serial/DrvHostSerial.cpp
    720   ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    721     VBoxDD_SOURCES.solaris += \
    722           Audio/DrvHostSolAudio.c
    723   else
    724     VBoxDD_SOURCES.solaris += \
    725           Audio/solaudio.c
    726   endif
    727   ifdef VBOX_WITH_SOLARIS_OSS
    728     ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    729       VBoxDD_SOURCES += Audio/DrvHostOssAudio.c
    730     else
    731       VBoxDD_SOURCES += Audio/ossaudio.c
    732     endif
    733     VBoxDD_DEFS += VBOX_WITH_SOLARIS_OSS
    734   endif
    735772  ifdef VBOX_WITH_SUID_WRAPPER
    736    VBoxDD_DEFS += VBOX_WITH_SUID_WRAPPER
    737   endif
    738  endif
    739 
    740  VBoxDD_DEFS.win       += VBOX_WITH_WIN_PARPORT_SUP
    741  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    742    VBoxDD_DEFS.win       += VBOX_WITH_PDM_AUDIO_DRIVER
    743  endif
    744  VBoxDD_SOURCES.win    += \
    745         Serial/DrvHostSerial.cpp \
     773   VBoxDD_DEFS    += VBOX_WITH_SUID_WRAPPER
     774  endif
     775 endif
     776
     777 VBoxDD_DEFS.win      += VBOX_WITH_WIN_PARPORT_SUP
     778 VBoxDD_SOURCES.win   += \
     779        Serial/DrvHostSerial.cpp \
    746780        Parallel/DrvHostParallel.cpp
    747 
    748  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    749  VBoxDD_SOURCES.win    += \
    750    Audio/DrvHostDSound.c
    751  else
    752  VBoxDD_SOURCES.win    += \
    753    Audio/dsoundaudio.c
    754  endif
    755 
    756  ifdef VBOX_WITH_VIRTUALKD
    757   VBoxDD_DEFS.win     += VBOX_WITH_VIRTUALKD
    758   VBoxDD_SOURCES.win  += \
    759     Misc/VirtualKD.cpp
    760  endif
    761781
    762782 if defined(VBOX_WITH_NETFLT)
     
    13501370
    13511371 #
    1352  # The Intel PXE rom.
     1372 # The Intel PXE ROM.
    13531373 #
    13541374 INSTALLS += VBoxExtPackPuelInsRoms
  • trunk/src/VBox/Devices/build/VBoxDD.cpp

    r52506 r53442  
    284284        return rc;
    285285#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     286    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostNullAudio);
     287    if (RT_FAILURE(rc))
     288        return rc;
    286289# if defined(RT_OS_WINDOWS)
    287290    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostDSound);
  • trunk/src/VBox/Devices/build/VBoxDD.h

    r52473 r53442  
    119119extern const PDMDRVREG g_DrvAUDIO;
    120120#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     121extern const PDMDRVREG g_DrvHostNullAudio;
    121122# if defined(RT_OS_WINDOWS)
    122123extern const PDMDRVREG g_DrvHostDSound;
  • trunk/src/VBox/Devices/testcase/Makefile.kmk

    r52259 r53442  
    55
    66#
    7 # Copyright (C) 2006-2012 Oracle Corporation
     7# Copyright (C) 2006-2014 Oracle Corporation
    88#
    99# This file is part of VirtualBox Open Source Edition (OSE), as
     
    2626BLDDIRS += $(VBOX_DEVICES_TEST_OUT_DIR)
    2727
     28## @todo Sort the features alphabetically!
    2829VBOX_DEVICES_TESTS_FEATURES = \
    2930        $(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,) \
     
    4445        $(if $(VBOX_WITH_VIDEOHWACCEL),VBOX_WITH_VIDEOHWACCEL,) \
    4546        $(if $(VBOX_WITH_PCI_PASSTHROUGH_IMPL),VBOX_WITH_PCI_PASSTHROUGH_IMPL,) \
    46         $(if $(VBOX_WITH_VMSVGA),VBOX_WITH_VMSVGA,)
     47        $(if $(VBOX_WITH_VMSVGA),VBOX_WITH_VMSVGA,) \
     48        $(if $(VBOX_WITH_PDM_AUDIO_DRIVER),VBOX_WITH_PDM_AUDIO_DRIVER,)
    4749
    4850
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSize.cpp

    r52817 r53442  
    77
    88/*
    9  * Copyright (C) 2006-2012 Oracle Corporation
     9 * Copyright (C) 2006-2014 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    105105#endif
    106106
    107 #undef LOG_GROUP
     107#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     108# undef LOG_GROUP
     109# include <VBox/vmm/pdmaudioifs.h>
     110#endif
    108111#include "../Audio/DevIchHda.cpp"
    109112
  • trunk/src/VBox/Main/Makefile.kmk

    r53242 r53442  
    745745ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    746746 VBoxC_SOURCES += \
     747        ../Devices/Audio/AudioMixBuffer.cpp \
     748        ../Devices/Audio/DrvAudioCommon.cpp \
    747749        src-client/DrvAudioVRDE.cpp
    748750else
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r53407 r53442  
    4040class AudioSniffer;
    4141#endif
     42class AudioVRDE;
    4243class Nvram;
    4344#ifdef VBOX_WITH_USB_CARDREADER
  • trunk/src/VBox/Main/src-client/AudioSnifferInterface.cpp

    r51612 r53442  
    2626#include <VBox/vmm/cfgm.h>
    2727#include <VBox/err.h>
     28
     29#ifdef LOG_GROUP
     30 #undef LOG_GROUP
     31#endif
     32#define LOG_GROUP LOG_GROUP_DEV_AUDIO
     33#include <VBox/log.h>
    2834
    2935//
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r53407 r53442  
    414414    , mpVmm2UserMethods(NULL)
    415415    , m_pVMMDev(NULL)
    416 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER
     416#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     417    , mAudioVRDE(NULL)
     418#else
    417419    , mAudioSniffer(NULL)
    418420#endif
     
    596598#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    597599        unconst(mAudioVRDE) = new AudioVRDE(this);
    598         AssertComRCReturnRC(rc);
     600        AssertReturn(mAudioVRDE, E_FAIL);
    599601#else
    600602        unconst(mAudioSniffer) = new AudioSniffer(this);
    601603        AssertReturn(mAudioSniffer, E_FAIL);
    602604#endif
    603 
    604605        FirmwareType_T enmFirmwareType;
    605606        mMachine->COMGETTER(FirmwareType)(&enmFirmwareType);
     
    730731    }
    731732#endif
    732 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER
     733
     734#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     735    if (mAudioVRDE)
     736    {
     737        delete mAudioVRDE;
     738        unconst(mAudioVRDE) = NULL;
     739    }
     740#else
    733741    if (mAudioSniffer)
    734742    {
     
    14331441    if (fu32Intercepted & VRDE_CLIENT_INTERCEPT_AUDIO)
    14341442    {
     1443#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1444        if (mAudioVRDE)
     1445            mAudioVRDE->onVRDEInputIntercept(false /* fIntercept */);
     1446#else
    14351447        mcAudioRefs--;
    14361448
    14371449        if (mcAudioRefs <= 0)
    14381450        {
    1439 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    14401451            if (mAudioSniffer)
    14411452            {
    14421453                PPDMIAUDIOSNIFFERPORT port = mAudioSniffer->getAudioSnifferPort();
    14431454                if (port)
    1444                 {
    14451455                    port->pfnSetup(port, false, false);
    1446                 }
    14471456            }
     1457        }
    14481458#endif
    1449         }
    14501459    }
    14511460
     
    14801489    AutoCaller autoCaller(this);
    14811490    AssertComRCReturnVoid(autoCaller.rc());
    1482 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    1483     LogFlowFunc(("mAudioSniffer %p, u32ClientId %d.\n",
    1484                  mAudioSniffer, u32ClientId));
    1485     NOREF(u32ClientId);
    1486 #endif
    1487 
     1491
     1492    LogFlowFunc(("u32ClientId=%RU32\n", u32ClientId));
     1493
     1494#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1495    if (mAudioVRDE)
     1496        mAudioVRDE->onVRDEInputIntercept(true /* fIntercept */);
     1497#else
    14881498    ++mcAudioRefs;
    14891499
    14901500    if (mcAudioRefs == 1)
    14911501    {
    1492 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    14931502        if (mAudioSniffer)
    14941503        {
    14951504            PPDMIAUDIOSNIFFERPORT port = mAudioSniffer->getAudioSnifferPort();
    14961505            if (port)
    1497             {
    14981506                port->pfnSetup(port, true, true);
    1499             }
    1500         }
     1507        }
     1508    }
    15011509#endif
    1502     }
    15031510
    15041511    LogFlowFuncLeave();
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r53407 r53442  
    26122612        InsertConfigInteger(pCfg,  "Object", (uintptr_t)pAudioSniffer);
    26132613#endif
    2614 
    26152614        /*
    2616          * AC'97 ICH / SoundBlaster16 audio / Intel HD Audio
     2615         * AC'97 ICH / SoundBlaster16 audio / Intel HD Audio.
    26172616         */
    26182617        BOOL fAudioEnabled = FALSE;
     
    26302629                case AudioControllerType_AC97:
    26312630                {
    2632                     /* default: ICH AC97 */
     2631                    /* Default: ICH AC97. */
    26332632                    InsertConfigNode(pDevices, "ichac97", &pDev);
    26342633                    InsertConfigNode(pDev,     "0", &pInst);
     
    26402639                case AudioControllerType_SB16:
    26412640                {
    2642                     /* legacy SoundBlaster16 */
     2641                    /* Legacy SoundBlaster16. */
    26432642                    InsertConfigNode(pDevices, "sb16", &pDev);
    26442643                    InsertConfigNode(pDev,     "0", &pInst);
     
    26542653                case AudioControllerType_HDA:
    26552654                {
    2656                     /* Intel HD Audio */
     2655                    /* Intel HD Audio. */
    26572656                    InsertConfigNode(pDevices, "hda", &pDev);
    26582657                    InsertConfigNode(pDev,     "0", &pInst);
     
    26632662            }
    26642663
    2665             /* the Audio driver */
     2664            /* The audio driver. */
    26662665            InsertConfigNode(pInst,    "LUN#0", &pLunL0);
    26672666            InsertConfigString(pLunL0, "Driver", "AUDIO");
     2667            InsertConfigNode(pLunL0,   "Config", &pCfg);
    26682668
    26692669#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2670            PCFGMNODE pLunL1;
    26702671            InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
    2671             InsertConfigString(pLunL1, "Driver", "PulseAudio");
     2672            InsertConfigNode(pLunL1, "Config", &pCfg);
    26722673#endif
    2673 
    2674             InsertConfigNode(pLunL0,   "Config", &pCfg);
    2675 
    26762674            AudioDriverType_T audioDriver;
    26772675            hrc = audioAdapter->COMGETTER(AudioDriver)(&audioDriver);                       H();
     
    26802678                case AudioDriverType_Null:
    26812679                {
     2680#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2681                    InsertConfigString(pLunL1, "Driver", "NullAudio");
     2682#else
    26822683                    InsertConfigString(pCfg, "AudioDriver", "null");
     2684#endif
    26832685                    break;
    26842686                }
    26852687#ifdef RT_OS_WINDOWS
    2686 #ifdef VBOX_WITH_WINMM
     2688# ifdef VBOX_WITH_WINMM
    26872689                case AudioDriverType_WinMM:
    26882690                {
     2691#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2692                    #error "Port WinMM audio backend!" /** @todo Still needed? */
     2693#else
    26892694                    InsertConfigString(pCfg, "AudioDriver", "winmm");
     2695#endif
    26902696                    break;
    26912697                }
    2692 #endif
     2698# endif
    26932699                case AudioDriverType_DirectSound:
    26942700                {
    26952701#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2696                     InsertConfigString(pCfg, "AudioDriver", "DSoundAudio");
     2702                    InsertConfigString(pLunL1, "Driver", "DSoundAudio");
    26972703#else
    26982704                    InsertConfigString(pCfg, "AudioDriver", "dsound");
     
    27042710                case AudioDriverType_SolAudio:
    27052711                {
     2712#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2713                    #error "Port Solaris audio backend!" /** @todo Port Solaris driver. */
     2714#else
    27062715                    InsertConfigString(pCfg, "AudioDriver", "solaudio");
    2707                     break;
    2708                 }
    2709 #endif
    2710 #ifdef RT_OS_LINUX
    2711 # ifdef VBOX_WITH_ALSA
    2712                 case AudioDriverType_ALSA:
    2713                 {
    2714 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2715                     InsertConfigString(pCfg, "AudioDriver", "AlsaAudio");
    2716 #else
    2717                     InsertConfigString(pCfg, "AudioDriver", "alsa");
    27182716#endif
    27192717                    break;
    27202718                }
     2719#endif
     2720#ifdef VBOX_WITH_ALSA
     2721                case AudioDriverType_ALSA:
     2722                {
     2723# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2724                    InsertConfigString(pLunL1, "Driver", "AlsaAudio");
     2725# else
     2726                    InsertConfigString(pCfg, "AudioDriver", "alsa");
    27212727# endif
    2722 # ifdef VBOX_WITH_PULSE
     2728                    break;
     2729                }
     2730#endif
     2731#ifdef VBOX_WITH_PULSE
    27232732                case AudioDriverType_Pulse:
    27242733                {
    2725 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2726                     InsertConfigString(pCfg, "AudioDriver", "PulseAudio");
    2727 #else
     2734# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2735                    InsertConfigString(pLunL1, "Driver", "PulseAudio");
     2736# else
    27282737                    InsertConfigString(pCfg, "AudioDriver", "pulse");
     2738# endif
     2739                    break;
     2740                }
    27292741#endif
    2730                     break;
    2731                 }
    2732 # endif
    2733 #endif /* RT_OS_LINUX */
    27342742#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(VBOX_WITH_SOLARIS_OSS)
    27352743                case AudioDriverType_OSS:
    27362744                {
    2737                     InsertConfigString(pCfg, "AudioDriver", "oss");
     2745# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2746                    #error "Port OSS audio backend!" /** @todo Port OSS driver. */
     2747# else
     2748                    InsertConfigString(pCfg, "AudioDriver", "ossaudio");
     2749# endif
    27382750                    break;
    27392751                }
    2740 #endif
    2741 #ifdef RT_OS_FREEBSD
    2742 # ifdef VBOX_WITH_PULSE
    2743                 case AudioDriverType_Pulse:
    2744                 {
    2745 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2746                     InsertConfigString(pCfg, "AudioDriver", "PulseAudio");
    2747 #else
    2748                     InsertConfigString(pCfg, "AudioDriver", "pulse");
    2749 #endif
    2750                     break;
    2751                 }
    2752 # endif
    27532752#endif
    27542753#ifdef RT_OS_DARWIN
    27552754                case AudioDriverType_CoreAudio:
    27562755                {
     2756# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2757                    InsertConfigString(pLunL1, "Driver", "CoreAudio");
     2758# else
    27572759                    InsertConfigString(pCfg, "AudioDriver", "coreaudio");
     2760# endif
    27582761                    break;
    27592762                }
    27602763#endif
    27612764            }
     2765
    27622766            hrc = pMachine->COMGETTER(Name)(bstr.asOutParam());                             H();
    2763             InsertConfigString(pCfg, "StreamName", bstr);
     2767
    27642768#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    2765             /* the Audio driver */
    2766             InsertConfigNode(pInst, "LUN#1", &pLunL0);
    2767             InsertConfigString(pLunL0, "Driver", "AUDIO");
    2768             InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
     2769            /*
     2770             * The VRDE audio backend driver. This one always is there
     2771             * and therefore is hardcoded here.
     2772             */
     2773            InsertConfigNode(pInst, "LUN#1", &pLunL1);
     2774            InsertConfigString(pLunL1, "Driver", "AUDIO");
     2775
     2776            InsertConfigNode(pLunL1, "AttachedDriver", &pLunL1);
    27692777            InsertConfigString(pLunL1, "Driver", "AudioVRDE");
    2770             InsertConfigNode(pLunL0, "Config", &pCfg);
     2778
     2779            InsertConfigNode(pLunL1, "Config", &pCfg);
    27712780            InsertConfigString(pCfg, "AudioDriver", "AudioVRDE");
    27722781            InsertConfigString(pCfg, "StreamName", bstr);
    2773             InsertConfigNode(pLunL1, "Config", &pCfg);
    2774             InsertConfigInteger(pCfg,  "Object", (uintptr_t)mAudioVRDE);
    2775             InsertConfigInteger(pCfg,  "ObjectVRDPServer", (uintptr_t)mConsoleVRDPServer);
    2776 
     2782            InsertConfigInteger(pCfg, "Object", (uintptr_t)mAudioVRDE);
     2783            InsertConfigInteger(pCfg, "ObjectVRDPServer", (uintptr_t)mConsoleVRDPServer);
     2784
     2785            /** @todo Add audio video recording driver here. */
    27772786#endif
    27782787        }
  • trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp

    r52978 r53442  
    946946                                                                   uint32_t fu32Intercepted)
    947947{
    948     ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback);
    949 
    950     server->mConsole->i_VRDPClientDisconnect(u32ClientId, fu32Intercepted);
    951 
    952     if (ASMAtomicReadU32(&server->mu32AudioInputClientId) == u32ClientId)
    953     {
    954         Log(("AUDIOIN: disconnected client %u\n", u32ClientId));
    955         ASMAtomicWriteU32(&server->mu32AudioInputClientId, 0);
     948    ConsoleVRDPServer *pServer = static_cast<ConsoleVRDPServer*>(pvCallback);
     949    AssertPtrReturnVoid(pServer);
     950
     951    pServer->mConsole->i_VRDPClientDisconnect(u32ClientId, fu32Intercepted);
     952
     953    if (ASMAtomicReadU32(&pServer->mu32AudioInputClientId) == u32ClientId)
     954    {
     955        LogFunc(("Disconnected client %u\n", u32ClientId));
     956        ASMAtomicWriteU32(&pServer->mu32AudioInputClientId, 0);
    956957
    957958#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    958         server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputIntercept(false);
     959        pServer->mConsole->i_getAudioVRDE()->onVRDEInputIntercept(false);
    959960#else
    960         PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->i_getAudioSniffer()->getAudioSnifferPort();
     961        PPDMIAUDIOSNIFFERPORT pPort = pServer->mConsole->i_getAudioSniffer()->getAudioSnifferPort();
    961962        if (pPort)
    962963        {
     
    970971    }
    971972
    972     int c = ASMAtomicDecS32(&server->mcClients);
    973     if (c == 0)
     973    int32_t cClients = ASMAtomicDecS32(&pServer->mcClients);
     974    if (cClients == 0)
    974975    {
    975976        /* Features which should be enabled only if there is a client. */
    976         server->remote3DRedirect(false);
     977        pServer->remote3DRedirect(false);
    977978    }
    978979}
     
    981982                                                           void **ppvIntercept)
    982983{
    983     ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback);
     984    ConsoleVRDPServer *pServer = static_cast<ConsoleVRDPServer*>(pvCallback);
    984985
    985986    LogFlowFunc(("%x\n", fu32Intercept));
     
    991992        case VRDE_CLIENT_INTERCEPT_AUDIO:
    992993        {
    993             server->mConsole->i_VRDPInterceptAudio(u32ClientId);
     994            pServer->mConsole->i_VRDPInterceptAudio(u32ClientId);
    994995            if (ppvIntercept)
    995996            {
    996                 *ppvIntercept = server;
     997                *ppvIntercept = pServer;
    997998            }
    998999            rc = VINF_SUCCESS;
     
    10011002        case VRDE_CLIENT_INTERCEPT_USB:
    10021003        {
    1003             server->mConsole->i_VRDPInterceptUSB(u32ClientId, ppvIntercept);
     1004            pServer->mConsole->i_VRDPInterceptUSB(u32ClientId, ppvIntercept);
    10041005            rc = VINF_SUCCESS;
    10051006        } break;
     
    10071008        case VRDE_CLIENT_INTERCEPT_CLIPBOARD:
    10081009        {
    1009             server->mConsole->i_VRDPInterceptClipboard(u32ClientId);
     1010            pServer->mConsole->i_VRDPInterceptClipboard(u32ClientId);
    10101011            if (ppvIntercept)
    10111012            {
    1012                 *ppvIntercept = server;
     1013                *ppvIntercept = pServer;
    10131014            }
    10141015            rc = VINF_SUCCESS;
     
    10201021             * Only one client is allowed to intercept audio input.
    10211022             */
    1022             if (ASMAtomicCmpXchgU32(&server->mu32AudioInputClientId, u32ClientId, 0) == true)
    1023             {
    1024                 Log(("AUDIOIN: connected client %u\n", u32ClientId));
     1023            if (ASMAtomicCmpXchgU32(&pServer->mu32AudioInputClientId, u32ClientId, 0) == true)
     1024            {
     1025                LogFunc(("Connected client %u\n", u32ClientId));
    10251026#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1026                 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputIntercept(true);
     1027                pServer->mConsole->i_getAudioVRDE()->onVRDEInputIntercept(true);
    10271028#else
    1028                 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->i_getAudioSniffer()->getAudioSnifferPort();
     1029                PPDMIAUDIOSNIFFERPORT pPort = pServer->mConsole->i_getAudioSniffer()->getAudioSnifferPort();
    10291030                if (pPort)
    10301031                {
    10311032                     pPort->pfnAudioInputIntercept(pPort, true);
    10321033                     if (ppvIntercept)
    1033                      {
    1034                          *ppvIntercept = server;
    1035                      }
     1034                         *ppvIntercept = pServer;
    10361035                }
    10371036                else
    10381037                {
    10391038                    AssertFailed();
    1040                     ASMAtomicWriteU32(&server->mu32AudioInputClientId, 0);
     1039                    ASMAtomicWriteU32(&pServer->mu32AudioInputClientId, 0);
    10411040                    rc = VERR_NOT_SUPPORTED;
    10421041                }
     
    10451044            else
    10461045            {
    1047                 Log(("AUDIOIN: ignored client %u, active client %u\n", u32ClientId, server->mu32AudioInputClientId));
     1046                Log(("AUDIOIN: ignored client %u, active client %u\n", u32ClientId, pServer->mu32AudioInputClientId));
    10481047                rc = VERR_NOT_SUPPORTED;
    10491048            }
     
    13061305                                                          uint32_t cbData)
    13071306{
    1308     ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback);
     1307    ConsoleVRDPServer *pServer = static_cast<ConsoleVRDPServer*>(pvCallback);
     1308    AssertPtrReturnVoid(pServer);
    13091309#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    1310     PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->i_getAudioSniffer()->getAudioSnifferPort();
     1310    PPDMIAUDIOSNIFFERPORT pPort = pServer->mConsole->i_getAudioSniffer()->getAudioSnifferPort();
    13111311#endif
    13121312
     
    13151315        case VRDE_AUDIOIN_BEGIN:
    13161316        {
     1317#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1318            pServer->mConsole->i_getAudioVRDE()->onVRDEInputBegin(pvCtx, (PVRDEAUDIOINBEGIN)pvData);
     1319#else
    13171320            const VRDEAUDIOINBEGIN *pParms = (const VRDEAUDIOINBEGIN *)pvData;
    1318 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1319             server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventBegin(pvCtx,
    1320                                                                                    VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt),
    1321                                                                                    VRDE_AUDIO_FMT_CHANNELS(pParms->fmt),
    1322                                                                                    VRDE_AUDIO_FMT_BITS_PER_SAMPLE(pParms->fmt),
    1323                                                                                    VRDE_AUDIO_FMT_SIGNED(pParms->fmt)
    1324                                                                                   );
    1325 #else
    13261321            pPort->pfnAudioInputEventBegin (pPort, pvCtx,
    13271322                                            VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt),
     
    13311326                                           );
    13321327#endif
    1333         } break;
     1328            break;
     1329        }
    13341330
    13351331        case VRDE_AUDIOIN_DATA:
    1336         {
    13371332#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1338             server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventData(pvCtx, pvData, cbData);
     1333            pServer->mConsole->i_getAudioVRDE()->onVRDEInputData(pvCtx, pvData, cbData);
    13391334#else
    13401335            pPort->pfnAudioInputEventData (pPort, pvCtx, pvData, cbData);
    13411336#endif
    1342         } break;
     1337            break;
    13431338
    13441339        case VRDE_AUDIOIN_END:
    1345         {
    13461340#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1347             server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventEnd(pvCtx);
     1341            pServer->mConsole->i_getAudioVRDE()->onVRDEInputEnd(pvCtx);
    13481342#else
    13491343            pPort->pfnAudioInputEventEnd (pPort, pvCtx);
    13501344#endif
    1351         } break;
     1345            break;
    13521346
    13531347        default:
    1354             return;
    1355     }
    1356 }
    1357 
     1348            break;
     1349    }
     1350}
    13581351
    13591352ConsoleVRDPServer::ConsoleVRDPServer(Console *console)
     
    39063899}
    39073900
    3908 /* @todo rc not needed? */
    39093901int ConsoleVRDPServer::SendAudioInputBegin(void **ppvUserCtx,
    39103902                                           void *pvContext,
     
    39143906                                           uint32_t cBits)
    39153907{
    3916     if (mpEntryPoints && mhServer && mpEntryPoints->VRDEAudioInOpen)
     3908    if (   mhServer
     3909        && mpEntryPoints && mpEntryPoints->VRDEAudioInOpen)
    39173910    {
    39183911        uint32_t u32ClientId = ASMAtomicReadU32(&mu32AudioInputClientId);
     
    39203913        {
    39213914            VRDEAUDIOFORMAT audioFormat = VRDE_AUDIO_FMT_MAKE(iSampleHz, cChannels, cBits, 0);
    3922             mpEntryPoints->VRDEAudioInOpen (mhServer,
    3923                                             pvContext,
    3924                                             u32ClientId,
    3925                                             audioFormat,
    3926                                             cSamples);
    3927 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    3928             //*ppvUserCtx = NULL;
    3929 #else
    3930             *ppvUserCtx = NULL; /* This is the ConsoleVRDPServer context.
    3931 -                                * Currently not used because only one client is allowed to
    3932 -                                * do audio input and the client id is saved by the ConsoleVRDPServer.
    3933 -                                */
    3934 #endif
    3935 
     3915            mpEntryPoints->VRDEAudioInOpen(mhServer,
     3916                                           pvContext,
     3917                                           u32ClientId,
     3918                                           audioFormat,
     3919                                           cSamples);
     3920            if (ppvUserCtx)
     3921                *ppvUserCtx = NULL; /* This is the ConsoleVRDPServer context.
     3922                                     * Currently not used because only one client is allowed to
     3923                                     * do audio input and the client ID is saved by the ConsoleVRDPServer.
     3924                                     */
    39363925            return VINF_SUCCESS;
    39373926        }
    39383927    }
     3928
     3929    /*
     3930     * Not supported or no client connected.
     3931     */
    39393932    return VERR_NOT_SUPPORTED;
    39403933}
     
    39513944    }
    39523945}
    3953 
    39543946
    39553947void ConsoleVRDPServer::QueryInfo(uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut) const
  • trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp

    r51096 r53442  
    11/* $Id$ */
    22/** @file
    3  *
    4  * VBox Audio VRDE backend
     3 * VRDE audio backend for Main.
    54 */
    65
    76/*
    8  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2013-2014 Oracle Corporation
    98 *
    109 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2221#include "Logging.h"
    2322
     23#include "../../Devices/Audio/DrvAudio.h"
     24#include "../../Devices/Audio/AudioMixBuffer.h"
     25
     26#include <iprt/mem.h>
     27#include <iprt/cdefs.h>
     28#include <iprt/circbuf.h>
     29
    2430#include <VBox/vmm/pdmaudioifs.h>
    2531#include <VBox/vmm/pdmdrv.h>
     
    2733#include <VBox/vmm/cfgm.h>
    2834#include <VBox/err.h>
    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. */
    43 typedef 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 */
    57 typedef IORINGBUFFER* PIORINGBUFFER;
    58 
    59 PPDMDRVINS gpDrvIns; //@todo handle this bad programming;
    60 
    61 static 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 
    82 static void IORingBufferDestroy(PIORINGBUFFER pBuffer)
    83 {
    84     if (pBuffer)
    85     {
    86         if (pBuffer->pBuffer)
    87             RTMemFree(pBuffer->pBuffer);
    88         RTMemFree(pBuffer);
    89     }
    90 }
    91 
    92 DECL_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 
    101 DECL_FORCE_INLINE(uint32_t) IORingBufferFree(PIORINGBUFFER pBuffer)
    102 {
    103     AssertPtr(pBuffer);
    104     return pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed);
    105 }
    106 
    107 DECL_FORCE_INLINE(uint32_t) IORingBufferUsed(PIORINGBUFFER pBuffer)
    108 {
    109     AssertPtr(pBuffer);
    110     return ASMAtomicReadU32(&pBuffer->cBufferUsed);
    111 }
    112 
    113 DECL_FORCE_INLINE(uint32_t) IORingBufferSize(PIORINGBUFFER pBuffer)
    114 {
    115     AssertPtr(pBuffer);
    116     return pBuffer->cBufSize;
    117 }
    118 
    119 static 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 
    146 DECL_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 
    155 static 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 
    182 DECL_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
    210 volume_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
    221 static 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 };
     35
     36#ifdef LOG_GROUP
     37 #undef LOG_GROUP
    23138#endif
     39#define LOG_GROUP LOG_GROUP_DEV_AUDIO
     40#include <VBox/log.h>
     41
    23242/**
    23343 * Audio VRDE driver instance data.
    234  *
    235  * @extends PDMIAUDIOSNIFFERCONNECTOR
    23644 */
    23745typedef struct DRVAUDIOVRDE
    23846{
    239     /** Pointer to audio VRDE object */
     47    /** Pointer to audio VRDE object. */
    24048    AudioVRDE           *pAudioVRDE;
    241     PPDMDRVINS          pDrvIns;
     49    PPDMDRVINS           pDrvIns;
    24250    /** Pointer to the driver instance structure. */
    243     PDMIHOSTAUDIO       IHostAudioR3;
    244     ConsoleVRDPServer *pConsoleVRDPServer;
     51    PDMIHOSTAUDIO        IHostAudioR3;
     52    ConsoleVRDPServer   *pConsoleVRDPServer;
    24553    /** Pointer to the DrvAudio port interface that is above it. */
    246     PPDMIAUDIOCONNECTOR       pUpPort;
     54    PPDMIAUDIOCONNECTOR  pDrvAudio;
    24755} DRVAUDIOVRDE, *PDRVAUDIOVRDE;
    248 typedef struct PDMHOSTVOICEOUT PDMHOSTVOICEOUT;
    249 typedef PDMHOSTVOICEOUT *PPDMHOSTVOICEOUT;
    250 
    251 typedef 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 };
    276 typedef VRDEVoice *PVRDEVoice;
    277 
    278 typedef struct VRDEVoiceOut
    279 {
    280     PDMHOSTVOICEOUT pHostVoiceOut;
     56
     57typedef struct VRDESTREAMIN
     58{
     59    /** Associated host input stream. */
     60    PDMAUDIOHSTSTRMIN    HstStrmIn;
     61    /** Number of samples captured asynchronously in the
     62     *  onVRDEInputXXX callbacks. */
     63    uint32_t             cSamplesCaptured;
     64    /** Critical section. */
     65    RTCRITSECT           CritSect;
     66
     67} VRDESTREAMIN, *PVRDESTREAMIN;
     68
     69typedef struct VRDESTREAMOUT
     70{
     71    /** Associated host output stream. */
     72    PDMAUDIOHSTSTRMOUT HstStrmOut;
    28173    uint64_t old_ticks;
    28274    uint64_t cSamplesSentPerSec;
    283 };
    284 typedef VRDEVoiceOut * PVRDEVoiceOut;
    285 
    286 AudioVRDE::AudioVRDE(Console *console)
    287     : mpDrv(NULL),
    288       mParent(console)
    289 {
    290 }
    291 
    292 AudioVRDE::~AudioVRDE()
    293 {
    294     if (mpDrv)
    295     {
    296         mpDrv->pAudioVRDE = NULL;
    297         mpDrv = NULL;
    298     }
    299 }
    300 
    301 PPDMIAUDIOCONNECTOR AudioVRDE::getDrvAudioPort()
    302 {
    303     Assert(mpDrv);
    304     return mpDrv->pUpPort;
    305 }
    306 
    307 void AudioVRDE::handleVRDESvrCmdAudioInputIntercept(bool fIntercept)
    308 {
    309     LogFlow(("AudioVRDE: handleVRDPCmdInputIntercept\n"));
    310 }
    311 
    312 static DECLCALLBACK(void *)  drvAudioVRDEInit(PPDMIHOSTAUDIO pInterface)
    313 {
    314     LogFlow(("drvAudioVRDEInit \n"));
    315     return 1;
    316 }
    317 
    318 static void drvAudioVRDEPcmInitInfo(PDMPCMPROPERTIES * pProps, audsettings_t *as)
    319 {
    320     int bits = 8, sign = 0, shift = 0;
    321     LogFlow(("AudioVRDE: PcmInitInfo \n"));
    322 
    323     switch (as->fmt) {
    324     case AUD_FMT_S8:
    325         sign = 1;
    326     case AUD_FMT_U8:
    327         break;
    328 
    329     case AUD_FMT_S16:
    330         sign = 1;
    331     case AUD_FMT_U16:
    332         bits = 16;
    333         shift = 1;
    334         break;
    335 
    336     case AUD_FMT_S32:
    337         sign = 1;
    338     case AUD_FMT_U32:
    339         bits = 32;
    340         shift = 2;
    341         break;
    342     }
    343 
    344     pProps->uFrequency = as->freq;
    345     pProps->cBits = bits;
    346     pProps->fSigned = sign;
    347     pProps->cChannels = as->nchannels;
    348     pProps->cShift = (as->nchannels == 2) + shift;
    349     pProps->fAlign = (1 << pProps->cShift) - 1;
    350     pProps->cbPerSec = pProps->uFrequency << pProps->cShift;
    351     pProps->fSwapEndian = (as->endianness != AUDIO_HOST_ENDIANNESS);
    352 }
    353 
    354 /*
    355  * Hard voice (playback)
    356  */
    357 static int audio_pcm_hw_find_min_out (PPDMHOSTVOICEOUT hw, int *nb_livep)
    358 {
    359     PPDMGSTVOICEOUT sw;
    360     PPDMGSTVOICEOUT pIter;
    361     int m = INT_MAX;
    362     int nb_live = 0;
    363     LogFlow(("Hard Voice Playback \n"));
    364 
    365     RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut)
    366     {
    367         sw = pIter;
    368         if (sw->State.fActive || !sw->State.fEmpty)
    369         {
    370             m = audio_MIN (m, sw->cSamplesMixed);
    371             nb_live += 1;
    372         }
    373     }
    374 
    375     *nb_livep = nb_live;
    376     return m;
    377 }
    378 
    379 int audio_pcm_hw_get_live_out2 (PPDMHOSTVOICEOUT hw, int *nb_live)
    380 {
    381     int smin;
    382 
    383     smin = audio_pcm_hw_find_min_out (hw, nb_live);
    384 
    385     if (!*nb_live) {
    386         return 0;
     75} VRDESTREAMOUT, *PVRDESTREAMOUT;
     76
     77static DECLCALLBACK(int) drvAudioVRDEInit(PPDMIHOSTAUDIO pInterface)
     78{
     79    LogFlowFuncEnter();
     80
     81    return VINF_SUCCESS;
     82}
     83
     84static DECLCALLBACK(int) drvAudioVRDEInitOut(PPDMIHOSTAUDIO pInterface,
     85                                             PPDMAUDIOHSTSTRMOUT pHstStrmOut, PPDMAUDIOSTREAMCFG pCfg,
     86                                             uint32_t *pcSamples)
     87{
     88    PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
     89    AssertPtrReturn(pDrv, VERR_INVALID_POINTER);
     90
     91    LogFlowFunc(("pHstStrmOut=%p, pCfg=%p\n", pHstStrmOut, pCfg));
     92
     93    PVRDESTREAMOUT pVRDEStrmOut = (PVRDESTREAMOUT)pHstStrmOut;
     94    AssertPtrReturn(pVRDEStrmOut, VERR_INVALID_POINTER);
     95
     96    if (pcSamples)
     97        *pcSamples = _4K; /** @todo Make this configurable. */
     98
     99    return drvAudioStreamCfgToProps(pCfg, &pVRDEStrmOut->HstStrmOut.Props);
     100}
     101
     102static DECLCALLBACK(int) drvAudioVRDEInitIn(PPDMIHOSTAUDIO pInterface,
     103                                            PPDMAUDIOHSTSTRMIN pHstStrmIn, PPDMAUDIOSTREAMCFG pCfg,
     104                                            PDMAUDIORECSOURCE enmRecSource,
     105                                            uint32_t *pcSamples)
     106{
     107    PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
     108    AssertPtrReturn(pDrv, VERR_INVALID_POINTER);
     109
     110    PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pHstStrmIn;
     111    AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER);
     112
     113    if (pcSamples)
     114        *pcSamples = _4K; /** @todo Make this configurable. */
     115
     116    return drvAudioStreamCfgToProps(pCfg, &pVRDEStrmIn->HstStrmIn.Props);
     117}
     118
     119/**
     120 * Transfers audio input formerly sent by a connected RDP client / VRDE backend
     121 * (using the onVRDEInputXXX methods) over to the VRDE host (VM). The audio device
     122 * emulation then will read and send the data to the guest.
     123 *
     124 * @return  IPRT status code.
     125 * @param   pInterface
     126 * @param   pHstStrmIn
     127 * @param   pcSamplesCaptured
     128 */
     129static DECLCALLBACK(int) drvAudioVRDECaptureIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn,
     130                                               uint32_t *pcSamplesCaptured)
     131{
     132    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     133    AssertPtrReturn(pHstStrmIn, VERR_INVALID_POINTER);
     134    AssertPtrReturn(pcSamplesCaptured, VERR_INVALID_POINTER);
     135
     136    PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
     137    AssertPtrReturn(pDrv, VERR_INVALID_POINTER);
     138
     139    PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pHstStrmIn;
     140    AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER);
     141
     142    /** @todo Use CritSect! */
     143
     144    int rc;
     145
     146    uint32_t cProcessed = 0;
     147    if (pVRDEStrmIn->cSamplesCaptured)
     148    {
     149        rc = audioMixBufMixToParent(&pVRDEStrmIn->HstStrmIn.MixBuf, pVRDEStrmIn->cSamplesCaptured,
     150                                    &cProcessed);
    387151    }
    388152    else
    389     {
    390         int live = smin;
    391 
    392         if (live < 0 || live > hw->cSamples)
    393         {
    394             LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
    395             return 0;
    396         }
    397         return live;
    398     }
    399 }
    400 
    401 
    402 int audio_pcm_hw_get_live_out (PPDMHOSTVOICEOUT hw)
    403 {
    404     int nb_live;
    405     int live;
    406 
    407     live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
    408     if (live < 0 || live > hw->cSamples)
    409     {
    410         LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
    411         return 0;
    412     }
    413     return live;
    414 }
    415 
    416 /*
    417  * Hard voice (capture)
    418  */
    419 static int audio_pcm_hw_find_min_in (PPDMHOSTVOICEIN hw)
    420 {
    421     PPDMGSTVOICEIN pIter;
    422     int m = hw->cSamplesCaptured;
    423 
    424     RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn)
    425     {
    426         if (pIter->State.fActive)
    427         {
    428             m = audio_MIN (m, pIter->cHostSamplesAcquired);
    429         }
    430     }
    431     return m;
    432 }
    433 
    434 int audio_pcm_hw_get_live_in (PPDMHOSTVOICEIN hw)
    435 {
    436     int live = hw->cSamplesCaptured - audio_pcm_hw_find_min_in (hw);
    437     if (live < 0 || live > hw->cSamples)
    438     {
    439         LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
    440         return 0;
    441     }
    442     return live;
    443 }
    444 
    445 static inline void *advance (void *p, int incr)
    446 {
    447     uint8_t *d = (uint8_t*)p;
    448     return (d + incr);
    449 }
    450 
    451 uint64_t audio_get_ticks_per_sec (void)
    452 {
    453     return PDMDrvHlpTMGetVirtualFreq (gpDrvIns);
    454 }
    455 
    456 uint64_t audio_get_clock (void)
    457 {
    458     return PDMDrvHlpTMGetVirtualTime (gpDrvIns);
    459 }
    460 
    461 void VRDEReallocSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples)
    462 {
    463     uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE);
    464     if (cbBuffer > pVRDEVoice->cbSamplesBufferAllocated)
    465     {
    466         if (pVRDEVoice->pvSamplesBuffer)
    467         {
    468             RTMemFree(pVRDEVoice->pvSamplesBuffer);
    469             pVRDEVoice->pvSamplesBuffer = NULL;
    470         }
    471         pVRDEVoice->pvSamplesBuffer = RTMemAlloc(cbBuffer);
    472         if (pVRDEVoice->pvSamplesBuffer)
    473             pVRDEVoice->cbSamplesBufferAllocated = cbBuffer;
    474         else
    475             pVRDEVoice->cbSamplesBufferAllocated = 0;
    476     }
    477 
    478 }
    479 
    480 void VRDEReallocRateAdjSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples)
    481 {
    482     uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE);
    483     if (cbBuffer > pVRDEVoice->cbRateBufferAllocated)
    484     {
    485         RTMemFree(pVRDEVoice->pvRateBuffer);
    486         pVRDEVoice->pvRateBuffer = RTMemAlloc(cbBuffer);
    487         if (pVRDEVoice->pvRateBuffer)
    488             pVRDEVoice->cbRateBufferAllocated = cbBuffer;
    489         else
    490             pVRDEVoice->cbRateBufferAllocated = 0;
    491     }
    492 }
    493 
    494 /*******************************************************************************
     153        rc = VINF_SUCCESS;
     154
     155    if (RT_SUCCESS(rc))
     156    {
     157        *pcSamplesCaptured = cProcessed;
     158
     159        Assert(pVRDEStrmIn->cSamplesCaptured >= cProcessed);
     160        pVRDEStrmIn->cSamplesCaptured -= cProcessed;
     161    }
     162
     163    LogFlowFunc(("cSamplesCaptured=%RU32, cProcessed=%RU32\n",
     164                 pVRDEStrmIn->cSamplesCaptured, cProcessed, rc));
     165    return rc;
     166}
     167
     168/**
     169 * Transfers VM audio output over to the VRDE instance for playing remotely
     170 * on the client.
    495171 *
    496  * AudioVRDE input section
    497  *
    498  ******************************************************************************/
    499 
    500 /*
    501  * Callback to feed audio input buffer. Samples format is be the same as
    502  * in the voice. The caller prepares st_sample_t.
    503  *
    504  * @param cbSamples Size of pvSamples array in bytes.
    505  * @param pvSamples Points to an array of samples.
    506  *
    507  * @return IPRT status code.
    508  */
    509 static int fltRecordingCallback(PVRDEVoice pVRDEVoice, uint32_t cbSamples, const void *pvSamples)
    510 {
    511     int rc = VINF_SUCCESS;
    512     uint32_t csAvail = 0;
    513     uint32_t csToWrite = 0;
    514     uint32_t cbToWrite = 0;
    515     uint32_t csWritten = 0;
    516     char *pcDst = NULL;
    517 
    518     LogFlow(("audio-filter: fltRecordingCallback\n"));
    519 
    520     Assert((cbSamples % sizeof(PDMHOSTSTEREOSAMPLE)) == 0);
    521 
    522     if (!pVRDEVoice->fIsInit)
    523         return VINF_SUCCESS;
    524 
    525     /* If nothing is pending return immediately. */
    526     if (cbSamples == 0)
    527         return VINF_SUCCESS;
    528 
    529     /* How much space is free in the ring buffer? */
    530     PPDMHOSTSTEREOSAMPLE psSrc;
    531     csAvail = IORingBufferFree(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE); /* bytes -> samples */
    532 
    533     /* How much space is used in the audio buffer. Use the smaller size of the too. */
    534     csAvail = RT_MIN(csAvail, cbSamples / sizeof(PDMHOSTSTEREOSAMPLE));
    535 
    536     /* Iterate as long as data is available */
    537     while(csWritten < csAvail)
    538     {
    539         /* How much is left? */
    540         csToWrite = csAvail - csWritten;
    541         cbToWrite = csToWrite * sizeof(PDMHOSTSTEREOSAMPLE);
    542 
    543         /* Try to acquire the necessary space from the ring buffer. */
    544         IORingBufferAquireWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite, &pcDst, &cbToWrite);
    545 
    546         /* How much do we get? */
    547         csToWrite = cbToWrite / sizeof(PDMHOSTSTEREOSAMPLE);
    548 
    549             /* Break if nothing is free anymore. */
    550         if (RT_UNLIKELY(csToWrite == 0))
    551             break;
    552 
    553         /* Copy the data from the audio buffer to the ring buffer in PVRDEVoice. */
    554         memcpy(pcDst, (uint8_t *)pvSamples + (csWritten * sizeof(PDMHOSTSTEREOSAMPLE)), cbToWrite);
    555 
    556         /* Release the ring buffer, so the main thread could start reading this data. */
    557         IORingBufferReleaseWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite);
    558 
    559         csWritten += csToWrite;
    560     }
    561 
    562     LogFlow(("AudioVRDE: [Input] Finished writing buffer with %RU32 samples (%RU32 bytes)\n",
    563               csWritten, csWritten * sizeof(PDMHOSTSTEREOSAMPLE)));
    564 
    565     return rc;
    566 }
    567 
    568 
    569 STDMETHODIMP AudioVRDE::handleVRDESvrCmdAudioInputEventBegin(void *pvContext, int iSampleHz, int cChannels,
    570                                                              int cBits, bool fUnsigned)
    571 {
    572     int bitIdx;
    573     PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext;
    574     LogFlow(("AudioVRDE: handleVRDPCmdInputEventBegin\n"));
    575     /* Prepare a format convertion for the actually used format. */
    576     pVRDEVoice->cBytesPerFrame = ((cBits + 7) / 8) * cChannels;
    577     if (cBits == 16)
    578     {
    579         bitIdx = 1;
    580     }
    581     else if (cBits == 32)
    582     {
    583         bitIdx = 2;
    584     }
    585     else
    586     {
    587         bitIdx = 0;
    588     }
    589     //PPDMIAUDIOCONNECTOR pPort = server->mConsole->getAudioVRDE()->getDrvAudioPort();
    590     /* Call DrvAudio interface to get the t_sample type conversion function */
    591     pVRDEVoice->convAudioDevFmtToStSampl = mpDrv->pUpPort->pfnConvDevFmtToStSample(mpDrv->pUpPort,
    592                                                                                    (cChannels == 2) ? 1 : 0,
    593                                                                                    !fUnsigned, 0, bitIdx
    594                                                                                   );
    595     if (pVRDEVoice->convAudioDevFmtToStSampl)
    596     {
    597         LogFlow(("AudioVRDE: Failed to get the conversion function \n"));
    598     }
    599     LogFlow(("AudioVRDE: Required freq as requested by VRDP Server = %d\n", iSampleHz));
    600     //if (iSampleHz && iSampleHz != pVRDEVoice->pHostVoiceIn.Props.uFrequency)
    601     {
    602         /* @todo if the above condition is false then pVRDEVoice->uFrequency will remain 0 */
    603         pVRDEVoice->rate = mpDrv->pUpPort->pfnPrepareAudioConversion(mpDrv->pUpPort, iSampleHz,
    604                                                                      pVRDEVoice->pHostVoiceIn.Props.uFrequency);
    605         pVRDEVoice->uFrequency = iSampleHz;
    606         LogFlow(("AudioVRDE: pVRDEVoice assigned requested freq =%d\n", pVRDEVoice->uFrequency));
    607     }
    608     return VINF_SUCCESS;
    609 }
    610 
    611 /*
    612  * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in
    613  *            drvAudioVRDEDisableEnableIn VOICE_ENABLE case.
    614  */
    615 void AudioVRDE::handleVRDESvrCmdAudioInputEventData(void *pvContext, const void *pvData, uint32_t cbData)
    616 {
    617     PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext;
    618     PPDMHOSTSTEREOSAMPLE pHostStereoSampleBuf; /* target sample buffer */
    619     PPDMHOSTSTEREOSAMPLE pConvertedSampleBuf; /* samples adjusted for rate */
    620     uint32_t cSamples = cbData / pVRDEVoice->cBytesPerFrame; /* Count of samples */
    621     void * pTmpSampleBuf = NULL;
    622     uint32_t cConvertedSamples; /* samples adjusted for rate */
    623     uint32_t cbSamples; /* count of bytes occupied by samples */
    624     uint32_t rc;
    625     LogFlow(("AudioVRDE: handleVRDPCmdInputEventData cbData = %d, bytesperfram=%d\n",
    626               cbData, pVRDEVoice->cBytesPerFrame));
    627 
    628     VRDEReallocSampleBuf(pVRDEVoice, cSamples);
    629     pHostStereoSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvSamplesBuffer;
    630     pVRDEVoice->convAudioDevFmtToStSampl(pHostStereoSampleBuf, pvData, cSamples, &nominal_volume);
    631 
    632     /* count of rate adjusted samples */
    633     pVRDEVoice->uFrequency = 22100; /* @todo handle this. How pVRDEVoice will get proper value */
    634     cConvertedSamples = (cSamples * pVRDEVoice->pHostVoiceIn.Props.uFrequency) / pVRDEVoice->uFrequency;
    635     VRDEReallocRateAdjSampleBuf(pVRDEVoice, cConvertedSamples);
    636 
    637     pConvertedSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvRateBuffer;
    638 
    639     if (pConvertedSampleBuf)
    640     {
    641         uint32_t cSampleSrc = cSamples;
    642         uint32_t cSampleDst = cConvertedSamples;
    643         mpDrv->pUpPort->pfnDoRateConversion(mpDrv->pUpPort, pVRDEVoice->rate, pHostStereoSampleBuf,
    644                                             pConvertedSampleBuf, &cSampleSrc, &cConvertedSamples);
    645         pTmpSampleBuf = pConvertedSampleBuf;
    646         cbSamples =  cConvertedSamples * sizeof(PDMHOSTSTEREOSAMPLE);
    647     }
    648 
    649     if (cbSamples)
    650     {
    651         rc = fltRecordingCallback(pVRDEVoice, cbSamples, pTmpSampleBuf);
    652     }
    653 }
    654 
    655 /*
    656  * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in
    657  *            drvAudioVRDEDisableEnableIn VOICE_ENABLE case.
    658  */
    659 void AudioVRDE::handleVRDESvrCmdAudioInputEventEnd(void *pvContext)
    660 {
    661     PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext;
    662     LogFlow(("AudioVRDE: handleVRDPCmdInputEventEnd\n"));
    663      /* The caller will not use this context anymore. */
    664     if (pVRDEVoice->rate)
    665     {
    666         mpDrv->pUpPort->pfnEndAudioConversion(mpDrv->pUpPort, pVRDEVoice->rate);
    667     }
    668 
    669     if (pVRDEVoice->pvSamplesBuffer)
    670     {
    671         RTMemFree(pVRDEVoice->pvSamplesBuffer);
    672         pVRDEVoice->pvSamplesBuffer = NULL;
    673     }
    674     if(pVRDEVoice->pvRateBuffer)
    675     {
    676         RTMemFree(pVRDEVoice->pvRateBuffer);
    677         pVRDEVoice->pvRateBuffer = NULL;
    678     }
    679 }
    680 
    681 static DECLCALLBACK(int)  drvAudioVRDEInitOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut, audsettings_t *as)
    682 {
    683     PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
    684 
    685     PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut;
    686     LogFlow(("DrvAudioVRDEInitOut: audio input begin cShift=%d\n", pHostVoiceOut->Props.cShift));
    687     pHostVoiceOut->cSamples =  6174;
    688     drvAudioVRDEPcmInitInfo(&pVRDEVoiceOut->pHostVoiceOut.Props, as);
    689     return VINF_SUCCESS;
    690 
    691 }
    692 
    693 static DECLCALLBACK(int) drvAudioVRDEInitIn (PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, audsettings_t *as)
    694 {
    695     LogFlow(("DrvAudioVRDE: drvAudioVRDEInitIn \n"));
    696     PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
    697     PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn;
    698     pHostVoiceIn->cSamples =  6174;
    699     drvAudioVRDEPcmInitInfo(&pVRDEVoice->pHostVoiceIn.Props, as);
    700     return VINF_SUCCESS;
    701 }
    702 
    703 static DECLCALLBACK(int) drvAudioVRDEPlayIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn)
    704 {
    705     uint32_t cbAvlblRingBuffer = 0;
    706     uint32_t cSamplesRingBuffer = 0;
    707     uint32_t cSamplesToRead = 0;
    708     uint32_t cSamplesRead = 0;
    709     uint32_t cbToRead;
    710     char *pcSrc;
    711     PDMHOSTSTEREOSAMPLE * psDst;
    712     //@todo take care of the size of the buffer allocated to pHostVoiceIn
    713     PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn;
    714     LogFlow(("DrvAudioVRDE: drvAudioVRDEPlayIn \n"));
    715 
    716  /* use this from DrvHostCoreAudio.c */
    717     if (ASMAtomicReadU32(&pVRDEVoice->status) != CA_STATUS_INIT)
    718     {
    719         LogFlow(("AudioVRDE: VRDE voice not initialized \n"));
    720         return 0;
    721     }
    722 
    723     /* how much space is used in the ring buffer in pRecordedVocieBuf with pAudioVRDE . Bytes-> samples*/
    724     cSamplesRingBuffer = IORingBufferUsed(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE);
    725 
    726     /* How much space is available in the mix buffer. Use the smaller size of the too. */
    727     cSamplesRingBuffer = RT_MIN(cSamplesRingBuffer, (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples -
    728                                audio_pcm_hw_get_live_in (&pVRDEVoice->pHostVoiceIn)));
    729     LogFlow(("AudioVRDE: [Input] Start reading buffer with %d samples (%d bytes)\n", cSamplesRingBuffer,
    730               cSamplesRingBuffer * sizeof(PDMHOSTSTEREOSAMPLE)));
    731 
    732     /* Iterate as long as data is available */
    733     while (cSamplesRead < cSamplesRingBuffer)
    734     {
    735         /* How much is left? Split request at the end of our samples buffer. */
    736         cSamplesToRead = RT_MIN(cSamplesRingBuffer - cSamplesRead,
    737                                 (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples - pVRDEVoice->pHostVoiceIn.offWrite));
    738         cbToRead = cSamplesToRead * sizeof(PDMHOSTSTEREOSAMPLE);
    739         LogFlow(("AudioVRDE: [Input] Try reading %RU32 samples (%RU32 bytes)\n", cSamplesToRead, cbToRead));
    740 
    741         /* Try to acquire the necessary block from the ring buffer. Remeber in fltRecrodCallback we
    742          * we are filling this buffer with the audio data available from VRDP. Here we are reading it
    743          */
    744         /*todo do I need to introduce a thread to fill the buffer in fltRecordcallback. So that
    745          * filling is in separate thread and the reading of that buffer is in separate thread
    746          */
    747         IORingBufferAquireReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead, &pcSrc, &cbToRead);
    748 
    749         /* How much to we get? */
    750         cSamplesToRead = cbToRead / sizeof(PDMHOSTSTEREOSAMPLE);
    751         LogFlow(("AuderVRDE: [Input] There are %d samples (%d bytes) available\n", cSamplesToRead, cbToRead));
    752 
    753         /* Break if nothing is used anymore. */
    754         if (cSamplesToRead == 0)
    755         {
    756             LogFlow(("AudioVRDE: Nothing to read \n"));
    757             break;
    758         }
    759 
    760         /* Copy the data from our ring buffer to the mix buffer. */
    761         psDst = pVRDEVoice->pHostVoiceIn.pConversionBuf + pVRDEVoice->pHostVoiceIn.offWrite;
    762         memcpy(psDst, pcSrc, cbToRead);
    763 
    764         /* Release the read buffer, so it could be used for new data. */
    765         IORingBufferReleaseReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead);
    766 
    767         pVRDEVoice->pHostVoiceIn.offWrite = (pVRDEVoice->pHostVoiceIn.offWrite + cSamplesToRead)
    768                                               % pVRDEVoice->pHostVoiceIn.cSamples;
    769 
    770         /* How much have we reads so far. */
    771         cSamplesRead += cSamplesToRead;
    772     }
    773     LogFlow(("AudioVRDE: [Input] Finished reading buffer with %d samples (%d bytes)\n",
    774                cSamplesRead, cSamplesRead * sizeof(PDMHOSTSTEREOSAMPLE)));
    775 
    776     return cSamplesRead;
    777 }
    778 
    779 static DECLCALLBACK(int) drvAudioVRDEPlayOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut)
    780 {
    781     PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
    782     PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut;
    783     int live;
    784     uint8_t     *pu8Dst;
    785     int cSamplesPlayed;
    786     int cSamplesToSend = 0;
     172 * @return  IPRT status code.
     173 * @param   pInterface
     174 * @param   pHstStrmOut
     175 * @param   pcSamplesPlayed
     176 */
     177static DECLCALLBACK(int) drvAudioVRDEPlayOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut,
     178                                             uint32_t *pcSamplesPlayed)
     179{
     180    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     181    AssertPtrReturn(pHstStrmOut, VERR_INVALID_POINTER);
     182    /* pcSamplesPlayed is optional. */
     183
     184    PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
     185    AssertPtrReturn(pDrv, VERR_INVALID_POINTER);
     186    PVRDESTREAMOUT pVRDEStrmOut = (PVRDESTREAMOUT)pHstStrmOut;
     187    AssertPtrReturn(pVRDEStrmOut, VERR_INVALID_POINTER);
     188
    787189    /*
    788190     * Just call the VRDP server with the data.
    789191     */
    790     live = audio_pcm_hw_get_live_out (pHostVoiceOut);
    791     uint64_t now = audio_get_clock();
    792     uint64_t ticks = now  - pVRDEVoiceOut->old_ticks;
    793     uint64_t ticks_per_second = audio_get_ticks_per_sec();
    794     cSamplesPlayed = (int)((2 * ticks * pHostVoiceOut->Props.uFrequency + ticks_per_second) / ticks_per_second / 2);
    795     if (cSamplesPlayed < 0)
     192    uint32_t live = drvAudioHstOutSamplesLive(pHstStrmOut, NULL /* pcStreamsLive */);
     193    uint64_t now = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns);
     194    uint64_t ticks = now  - pVRDEStrmOut->old_ticks;
     195    uint64_t ticks_per_second = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns);
     196
     197    uint32_t cSamplesPlayed = (int)((2 * ticks * pHstStrmOut->Props.uHz + ticks_per_second) / ticks_per_second / 2);
     198    if (!cSamplesPlayed)
    796199        cSamplesPlayed = live;
    797     pHostVoiceOut->Props.cBits = 128;
    798     VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pHostVoiceOut->Props.uFrequency,
    799                                                  pHostVoiceOut->Props.cChannels,
    800                                                  pHostVoiceOut->Props.cBits, /* bits per sample */
    801                                                  !pHostVoiceOut->Props.fSigned);
    802     LogFlow(("DrvAudioVRDE: send audio sample freq=%d, chan=%d, cBits = %d, fsigned = %d, cSamples=%d format=%d \n",
    803              pHostVoiceOut->Props.uFrequency, pHostVoiceOut->Props.cChannels,
    804              pHostVoiceOut->Props.cBits, pHostVoiceOut->Props.fSigned,
    805              pHostVoiceOut->cSamples, format)
    806             );
    807     pVRDEVoiceOut->old_ticks = now;
    808     cSamplesToSend = RT_MIN(live, cSamplesPlayed);
    809     if (pHostVoiceOut->offRead + cSamplesToSend > pHostVoiceOut->cSamples)
    810     {
    811         /* send the samples till the end of pHostStereoSampleBuf */
    812         pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead],
    813                                                    (pHostVoiceOut->cSamples - pHostVoiceOut->offRead), format);
    814         /*pHostStereoSampleBuff already has the samples which exceeded its space. They have overwriten the old
    815          * played sampled starting from offset 0. So based on the number of samples that we had to play,
    816          * read the number of samples from offset 0 .
    817          */
    818         pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[0],
    819                                                    (cSamplesToSend - (pHostVoiceOut->cSamples -
    820                                                                      pHostVoiceOut->offRead)),
    821                                                    format);
    822     }
    823     else
    824     {
    825         pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead],
    826                                                    cSamplesToSend, format);
    827     }
    828         pHostVoiceOut->offRead = (pHostVoiceOut->offRead + cSamplesToSend) % pHostVoiceOut->cSamples;
    829     return  cSamplesToSend;
    830 }
    831 
    832 static DECLCALLBACK(void) drvAudioVRDEFiniIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN hw)
    833 {
    834     PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
    835     LogFlow(("DrvAudioVRDE: drvAudioVRDEFiniIn \n"));
    836     pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL);
    837 }
    838 
    839 static DECLCALLBACK(void) drvAudioVRDEFiniOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut)
    840 {
    841     PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
    842     LogFlow(("DrvAudioVRDE: audio input end\n"));
    843 }
    844 
    845 static DECLCALLBACK(int) drvAudioVRDEDisableEnableOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT hw, int cmd)
    846 {
    847     LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableOut \n"));
    848     return VINF_SUCCESS;
    849 }
    850 
    851 static DECLCALLBACK(int) drvAudioVRDEDisableEnableIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, int cmd)
    852 {
    853     PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
    854 
    855     /* Initialize  VRDEVoice and return to VRDP server which returns this struct back to us
    856      * in the form void * pvContext
    857      */
    858     PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn;
    859     LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableIn \n"));
    860     /* initialize only if not already done */
    861     if (cmd == VOICE_ENABLE)
    862     {
    863         //@todo if (!pVRDEVoice->fIsInit)
    864         //    IORingBufferReset(pVRDEVoice->pRecordedVoiceBuf);
    865         LogFlow(("DrvAudioVRDE: Intializing the VRDE params and buffer \n"));
    866         pVRDEVoice->fIsInit = 1;
    867         pVRDEVoice->pHostVoiceIn = *pHostVoiceIn;
    868         pVRDEVoice->cBytesPerFrame =1 ;
    869         pVRDEVoice->uFrequency = 0;
    870         pVRDEVoice->rate = NULL;
    871         pVRDEVoice->cbSamplesBufferAllocated = 0;
    872         pVRDEVoice->pvRateBuffer = NULL;
    873         pVRDEVoice->cbRateBufferAllocated = 0;
    874 
    875         pVRDEVoice->pHostVoiceIn.cSamples = 2048;
    876         /* Initialize the hardware info section with the audio settings */
    877 
    878         ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_INIT);
    879 
    880         /* Create the internal ring buffer. */
    881         IORingBufferCreate(&pVRDEVoice->pRecordedVoiceBuf,
    882                            pVRDEVoice->pHostVoiceIn.cSamples * sizeof(PDMHOSTSTEREOSAMPLE));
    883 
    884         if (!RT_VALID_PTR(pVRDEVoice->pRecordedVoiceBuf))
     200
     201    VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pHstStrmOut->Props.uHz,
     202                                                 pHstStrmOut->Props.cChannels,
     203                                                 pHstStrmOut->Props.cBits,
     204                                                 pHstStrmOut->Props.fSigned);
     205
     206    LogFlowFunc(("hz=%d, chan=%d, cBits=%d, fSigned=%RTbool, format=%ld\n",
     207                 pHstStrmOut->Props.uHz, pHstStrmOut->Props.cChannels,
     208                 pHstStrmOut->Props.cBits, pHstStrmOut->Props.fSigned,
     209                 format));
     210
     211    pVRDEStrmOut->old_ticks = now;
     212    int cSamplesToSend = RT_MIN(live, cSamplesPlayed);
     213
     214    uint32_t cReadTotal = 0;
     215
     216    PPDMAUDIOSAMPLE pSamples;
     217    uint32_t cRead;
     218    int rc = audioMixBufAcquire(&pHstStrmOut->MixBuf, cSamplesToSend,
     219                                &pSamples, &cRead);
     220    if (RT_SUCCESS(rc))
     221    {
     222        cReadTotal = cRead;
     223        pDrv->pConsoleVRDPServer->SendAudioSamples(pSamples, cRead, format);
     224
     225        if (rc == VINF_TRY_AGAIN)
    885226        {
    886             LogRel(("AudioVRDE: [Input] Failed to create internal ring buffer\n"));
    887             return  VERR_NO_MEMORY;
     227            rc = audioMixBufAcquire(&pHstStrmOut->MixBuf, cSamplesToSend - cRead,
     228                                    &pSamples, &cRead);
     229            if (RT_SUCCESS(rc))
     230            {
     231                cReadTotal += cRead;
     232                pDrv->pConsoleVRDPServer->SendAudioSamples(pSamples, cRead, format);
     233            }
    888234        }
    889 
    890         ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_INIT);
    891         return pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pVRDEVoice, pHostVoiceIn->cSamples,
    892                                                              pHostVoiceIn->Props.uFrequency,
    893                                                              pHostVoiceIn->Props.cChannels, pHostVoiceIn->Props.cBits);
    894     }
    895     else if (cmd == VOICE_DISABLE)
    896     {
    897         LogFlow(("DrvAudioVRDE: Cmd to disable VRDE \n"));
    898         pVRDEVoice->fIsInit = 0;
    899         ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_UNINIT);
    900         IORingBufferDestroy(pVRDEVoice->pRecordedVoiceBuf);
    901         pVRDEVoice->pRecordedVoiceBuf = NULL;
    902         ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_UNINIT);
     235    }
     236
     237    audioMixBufFinish(&pHstStrmOut->MixBuf, cReadTotal);
     238
     239    if (pcSamplesPlayed)
     240        *pcSamplesPlayed = cReadTotal;
     241
     242    LogFlowFunc(("cSamplesToSend=%RU32, rc=%Rrc\n", cSamplesToSend, rc));
     243    return rc;
     244}
     245
     246static DECLCALLBACK(int) drvAudioVRDEFiniIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn)
     247{
     248    PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
     249    AssertPtrReturn(pDrv, VERR_INVALID_POINTER);
     250
     251    if (pDrv->pConsoleVRDPServer)
    903252        pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL);
    904     }
    905     return VINF_SUCCESS;
    906 }
    907 
    908 static DECLCALLBACK(void) drvAudioVRDEGetConf(PPDMIBASE pInterface, PPDMAUDIOCONF pAudioConf)
    909 {
    910     LogFlow(("drvAudioVRDE: drvAudioVRDEGetConf \n"));
    911     /* @todo check if szHostVoiceOut = sizeof VRDEVoice works. VRDEVoice doesn't contain HOSTVOICEOUT. */
    912     pAudioConf->szHostVoiceOut = sizeof(VRDEVoice);
    913     pAudioConf->szHostVoiceIn = sizeof(VRDEVoice);
    914     pAudioConf->MaxHostVoicesOut = 1;
    915     pAudioConf->MaxHostVoicesIn = 1;
     253
     254    return VINF_SUCCESS;
     255}
     256
     257static DECLCALLBACK(int) drvAudioVRDEFiniOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut)
     258{
     259    PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
     260    AssertPtrReturn(pDrv, VERR_INVALID_POINTER);
     261
     262    return VINF_SUCCESS;
     263}
     264
     265static DECLCALLBACK(int) drvAudioVRDEControlOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut,
     266                                                PDMAUDIOSTREAMCMD enmStreamCmd)
     267{
     268    PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
     269    AssertPtrReturn(pDrv, VERR_INVALID_POINTER);
     270
     271    LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd));
     272
     273    return VINF_SUCCESS;
     274}
     275
     276static DECLCALLBACK(int) drvAudioVRDEControlIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn2, /** @todo Fix param types! */
     277                                               PDMAUDIOSTREAMCMD enmStreamCmd)
     278{
     279    PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3);
     280    AssertPtrReturn(pDrv, VERR_INVALID_POINTER);
     281
     282    PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pHstStrmIn2;
     283    AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER);
     284
     285    PPDMAUDIOHSTSTRMIN pHstStrmIn = &pVRDEStrmIn->HstStrmIn;
     286
     287    LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd));
     288
     289    /* Initialize only if not already done. */
     290    if (enmStreamCmd == PDMAUDIOSTREAMCMD_ENABLE)
     291    {
     292        int rc2 = pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pVRDEStrmIn, audioMixBufSize(&pHstStrmIn->MixBuf),
     293                                                                pHstStrmIn->Props.uHz,
     294                                                                pHstStrmIn->Props.cChannels, pHstStrmIn->Props.cBits);
     295#ifdef DEBUG
     296        if (rc2 == VERR_NOT_SUPPORTED)
     297            LogFlowFunc(("No RDP client connected, so no input recording supported\n"));
     298#endif
     299    }
     300    else if (enmStreamCmd == PDMAUDIOSTREAMCMD_DISABLE)
     301        pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL /* pvUserCtx */);
     302
     303    return VINF_SUCCESS;
     304}
     305
     306static DECLCALLBACK(int) drvAudioVRDEGetConf(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pCfg)
     307{
     308    pCfg->cbStreamOut     = sizeof(VRDESTREAMOUT);
     309    pCfg->cbStreamIn      = sizeof(VRDESTREAMIN);
     310    pCfg->cMaxHstStrmsOut = 1;
     311    pCfg->cMaxHstStrmsIn  = 2; /* Microphone in + line in. */
     312
     313    return VINF_SUCCESS;
    916314}
    917315
     
    922320{
    923321    PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
    924     PDRVAUDIOVRDE  pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE);
     322    PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE);
     323
    925324    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
    926325    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, &pThis->IHostAudioR3);
     
    928327}
    929328
    930 
    931 static DECLCALLBACK(void) drvAudioVRDEDestruct(PPDMDRVINS pDrvIns)
    932 {
    933 }
    934 
    935 /**
    936  * Construct a DirectSound Audio driver instance.
     329AudioVRDE::AudioVRDE(Console *pConsole)
     330    : mpDrv(NULL),
     331      mParent(pConsole)
     332{
     333}
     334
     335AudioVRDE::~AudioVRDE(void)
     336{
     337    if (mpDrv)
     338    {
     339        mpDrv->pAudioVRDE = NULL;
     340        mpDrv = NULL;
     341    }
     342}
     343
     344int AudioVRDE::onVRDEInputIntercept(bool fIntercept)
     345{
     346    LogFlowThisFunc(("fIntercept=%RTbool\n", fIntercept));
     347    return VINF_SUCCESS; /* Never veto. */
     348}
     349
     350/**
     351 * Marks the beginning of sending captured audio data from a connected
     352 * RDP client.
     353 *
     354 * @return  IPRT status code.
     355 * @param   pvContext               The context; in this case a pointer to a
     356 *                                  VRDESTREAMIN structure.
     357 * @param   pVRDEAudioBegin         Pointer to a VRDEAUDIOINBEGIN structure.
     358 */
     359int AudioVRDE::onVRDEInputBegin(void *pvContext, PVRDEAUDIOINBEGIN pVRDEAudioBegin)
     360{
     361    AssertPtrReturn(pvContext, VERR_INVALID_POINTER);
     362    AssertPtrReturn(pVRDEAudioBegin, VERR_INVALID_POINTER);
     363
     364    PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pvContext;
     365    AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER);
     366
     367    VRDEAUDIOFORMAT audioFmt = pVRDEAudioBegin->fmt;
     368
     369    int iSampleHz  = VRDE_AUDIO_FMT_SAMPLE_FREQ(audioFmt);
     370    int cChannels  = VRDE_AUDIO_FMT_CHANNELS(audioFmt);
     371    int cBits      = VRDE_AUDIO_FMT_BITS_PER_SAMPLE(audioFmt);
     372    bool fUnsigned = VRDE_AUDIO_FMT_SIGNED(audioFmt);
     373
     374    /*pVRDEStrmIn->cbSample = VRDE_AUDIO_FMT_BYTES_PER_SAMPLE(audioFmt);
     375    pVRDEStrmIn->uHz      = iSampleHz;*/
     376
     377    LogFlowFunc(("cbSample=%RU32, iSampleHz=%d, cChannels=%d, cBits=%d, fUnsigned=%RTbool\n",
     378                 VRDE_AUDIO_FMT_BYTES_PER_SAMPLE(audioFmt), iSampleHz, cChannels, cBits, fUnsigned));
     379
     380    return VINF_SUCCESS;
     381}
     382
     383int AudioVRDE::onVRDEInputData(void *pvContext, const void *pvData, uint32_t cbData)
     384{
     385    PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pvContext;
     386    AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER);
     387
     388    PPDMAUDIOHSTSTRMIN pHstStrmIn = &pVRDEStrmIn->HstStrmIn;
     389    AssertPtrReturn(pHstStrmIn, VERR_INVALID_POINTER);
     390
     391    /** @todo Use CritSect! */
     392
     393    uint32_t cWritten;
     394    int rc = audioMixBufWriteCirc(&pHstStrmIn->MixBuf, pvData, cbData, &cWritten);
     395    if (RT_SUCCESS(rc))
     396        pVRDEStrmIn->cSamplesCaptured += cWritten;
     397
     398    LogFlowFunc(("cbData=%RU32, cWritten=%RU32, cSamplesCaptured=%RU32, rc=%Rrc\n",
     399                 cbData, cWritten, pVRDEStrmIn->cSamplesCaptured, rc));
     400    return rc;
     401}
     402
     403int AudioVRDE::onVRDEInputEnd(void *pvContext)
     404{
     405    NOREF(pvContext);
     406
     407    return VINF_SUCCESS;
     408}
     409
     410/**
     411 * Construct a VRDE audio driver instance.
    937412 *
    938413 * @copydoc FNPDMDRVCONSTRUCT
    939414 */
    940 DECLCALLBACK(int) AudioVRDE::drvAudioVRDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
     415/* static */
     416DECLCALLBACK(int) AudioVRDE::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
    941417{
    942418    PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE);
    943     LogRel(("drvAudioVRDEConstruct\n"));
    944 
    945     /* we save the address of AudioVRDE in Object node in CFGM tree and address of VRDP server in
    946      * ObjectVRDPServer node. So presence of both is necessary.
    947      */
    948     //if (!CFGMR3AreValuesValid(pCfg, "Object\0") || !CFGMR3AreValuesValid(pCfg, "ObjectVRDPServer\0"))
    949     //   return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
     419    LogRel(("Audio: Initializing VRDE driver\n"));
     420    LogFlowFunc(("fFlags=0x%x\n", fFlags));
     421
    950422    AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
    951423                    ("Configuration error: Not possible to attach anything to this driver!\n"),
     
    955427     * Init the static parts.
    956428     */
    957     pThis->pDrvIns                          = pDrvIns;
    958     gpDrvIns = pDrvIns;
     429    pThis->pDrvIns                    = pDrvIns;
    959430    /* IBase */
    960     pDrvIns->IBase.pfnQueryInterface        = drvAudioVRDEQueryInterface;
    961     pThis->IHostAudioR3.pfnInitIn           = drvAudioVRDEInitIn;
    962     pThis->IHostAudioR3.pfnInitOut          = drvAudioVRDEInitOut;
    963     pThis->IHostAudioR3.pfnDisableEnableOut = drvAudioVRDEDisableEnableOut;
    964     pThis->IHostAudioR3.pfnDisableEnableIn  = drvAudioVRDEDisableEnableIn;
    965     pThis->IHostAudioR3.pfnFiniIn           = drvAudioVRDEFiniIn;
    966     pThis->IHostAudioR3.pfnFiniOut          = drvAudioVRDEFiniOut;
    967     pThis->IHostAudioR3.pfnPlayIn           = drvAudioVRDEPlayIn;
    968     pThis->IHostAudioR3.pfnPlayOut          = drvAudioVRDEPlayOut;
    969     pThis->IHostAudioR3.pfnGetConf          = drvAudioVRDEGetConf;
    970     pThis->IHostAudioR3.pfnInit             = drvAudioVRDEInit;
    971 
    972     /* Get VRDPServer pointer */
    973     void *pv;
    974     int rc = CFGMR3QueryPtr(pCfg, "ObjectVRDPServer", &pv);
     431    pDrvIns->IBase.pfnQueryInterface  = drvAudioVRDEQueryInterface;
     432    pThis->IHostAudioR3.pfnInitIn     = drvAudioVRDEInitIn;
     433    pThis->IHostAudioR3.pfnInitOut    = drvAudioVRDEInitOut;
     434    pThis->IHostAudioR3.pfnControlOut = drvAudioVRDEControlOut;
     435    pThis->IHostAudioR3.pfnControlIn  = drvAudioVRDEControlIn;
     436    pThis->IHostAudioR3.pfnFiniIn     = drvAudioVRDEFiniIn;
     437    pThis->IHostAudioR3.pfnFiniOut    = drvAudioVRDEFiniOut;
     438    pThis->IHostAudioR3.pfnCaptureIn  = drvAudioVRDECaptureIn;
     439    pThis->IHostAudioR3.pfnPlayOut    = drvAudioVRDEPlayOut;
     440    pThis->IHostAudioR3.pfnGetConf    = drvAudioVRDEGetConf;
     441    pThis->IHostAudioR3.pfnInit       = drvAudioVRDEInit;
     442
     443    /* Get VRDPServer pointer. */
     444    void *pvUser;
     445    int rc = CFGMR3QueryPtr(pCfg, "ObjectVRDPServer", &pvUser);
    975446    if (RT_FAILURE(rc))
    976447    {
    977         AssertMsgFailed(("DrvAudioVRDE Confguration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
     448        AssertMsgFailed(("Confguration error: No/bad \"ObjectVRDPServer\" value, rc=%Rrc\n", rc));
    978449        return rc;
    979450    }
    980     /* CFGM tree saves the pointer to ConsoleVRDPServer in the Object node of AudioVRDE */
    981     pThis->pConsoleVRDPServer = (ConsoleVRDPServer *)pv;
    982     pv = NULL;
    983 
    984     rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
     451
     452    /* CFGM tree saves the pointer to ConsoleVRDPServer in the Object node of AudioVRDE. */
     453    pThis->pConsoleVRDPServer = (ConsoleVRDPServer *)pvUser;
     454
     455    pvUser = NULL;
     456    rc = CFGMR3QueryPtr(pCfg, "Object", &pvUser);
    985457    if (RT_FAILURE(rc))
    986458    {
    987         AssertMsgFailed(("DrvAudioVRDE Confguration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
     459        AssertMsgFailed(("Confguration error: No/bad \"Object\" value, rc=%Rrc\n", rc));
    988460        return rc;
    989461    }
    990     pThis->pAudioVRDE = (AudioVRDE *)pv;
     462
     463    pThis->pAudioVRDE = (AudioVRDE *)pvUser;
    991464    pThis->pAudioVRDE->mpDrv = pThis;
     465
    992466    /*
    993      * Get the interface for the above driver (DrvAudio) to make mixer/conversion calls .
     467     * Get the interface for the above driver (DrvAudio) to make mixer/conversion calls.
    994468     * Described in CFGM tree.
    995469     */
    996     pThis->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOCONNECTOR);
    997     if (!pThis->pUpPort)
    998     {
    999         AssertMsgFailed(("Configuration error: No Audio Sniffer port interface above!\n"));
     470    pThis->pDrvAudio = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOCONNECTOR);
     471    if (!pThis->pDrvAudio)
     472    {
     473        AssertMsgFailed(("Configuration error: No upper interface specified!\n"));
    1000474        return VERR_PDM_MISSING_INTERFACE_ABOVE;
    1001475    }
     
    1004478}
    1005479
    1006 
    1007 /**
    1008  * Char driver registration record.
    1009  */
    1010 const PDMDRVREG g_DrvAudioVRDE =
    1011 {
    1012      PDM_DRVREG_VERSION,
    1013    /* szName */
     480/* static */
     481DECLCALLBACK(void) AudioVRDE::drvDestruct(PPDMDRVINS pDrvIns)
     482{
     483    LogFlowFuncEnter();
     484}
     485
     486/**
     487 * VRDE audio driver registration record.
     488 */
     489const PDMDRVREG AudioVRDE::DrvReg =
     490{
     491    PDM_DRVREG_VERSION,
     492    /* szName */
    1014493    "AudioVRDE",
    1015494    /* szRCMod */
     
    1018497    "",
    1019498    /* pszDescription */
    1020     "Audio VRDE",
     499    "Audio driver for VRDE backend",
    1021500    /* fFlags */
    1022501    PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
     
    1028507    sizeof(DRVAUDIOVRDE),
    1029508    /* pfnConstruct */
    1030     AudioVRDE::drvAudioVRDEConstruct,
     509    AudioVRDE::drvConstruct,
    1031510    /* pfnDestruct */
    1032     drvAudioVRDEDestruct,
     511    AudioVRDE::drvDestruct,
    1033512    /* pfnRelocate */
    1034513    NULL,
     
    1055534};
    1056535
    1057 
    1058 
  • trunk/src/VBox/Main/src-client/VBoxDriversRegister.cpp

    r50686 r53442  
    7171    if (RT_FAILURE(rc))
    7272        return rc;
     73
    7374#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    74     rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvAudioVRDE);
     75    rc = pCallbacks->pfnRegister(pCallbacks, &AudioVRDE::DrvReg);
    7576#else
    7677    rc = pCallbacks->pfnRegister(pCallbacks, &AudioSniffer::DrvReg);
  • trunk/src/VBox/VMM/VMMR3/PDM.cpp

    r52670 r53442  
    55
    66/*
    7  * Copyright (C) 2006-2013 Oracle Corporation
     7 * Copyright (C) 2006-2014 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3838 * will call the entry point 'VBoxDevicesRegister' when loading a device module.
    3939 * The device module will then use the supplied callback table to check the VMM
    40  * version and to register its devices.  Each device have an unique (for the
     40 * version and to register its devices.  Each device has an unique (for the
    4141 * configured VM) name.  The name is not only used in PDM but also in CFGM (to
    4242 * organize device and device instance settings) and by anyone who wants to talk
     
    5252 * Some devices are trusted devices, most are not.  The trusted devices are an
    5353 * integrated part of the VM and can obtain the VM handle from their device
    54  * instance handles, thus enabling them to call any VM api.  Untrusted devices
     54 * instance handles, thus enabling them to call any VM API.  Untrusted devices
    5555 * can only use the callbacks provided during device instantiation.
    5656 *
     
    6464 * A device can provide a ring-0 and/or a raw-mode context extension to improve
    6565 * the VM performance by handling exits and traps (respectively) without
    66  * requiring context switches (to ring-3).  Callbacks for MMIO and I/O ports can
    67  * needs to be registered specifically for the additional contexts for this to
     66 * requiring context switches (to ring-3).  Callbacks for MMIO and I/O ports
     67 * need to be registered specifically for the additional contexts for this to
    6868 * make sense.  Also, the device has to be trusted to be loaded into R0/RC
    6969 * because of the extra privilege it entails.  Note that raw-mode code and data
     
    104104 * The way USB devices work differs greatly from other devices though since they
    105105 * aren't attaches directly to the PCI/ISA/whatever system buses but via a
    106  * USB host control (OHCI, UHCI or EHCI).  USB devices handles USB requests
     106 * USB host control (OHCI, UHCI or EHCI).  USB devices handle USB requests
    107107 * (URBs) and does not register I/O ports, MMIO ranges or PCI bus
    108108 * devices/functions.
     
    120120 * controller, an ATA controller or a SATA controller.  The basics of the DVD/CD
    121121 * drive implementation remains the same - eject, insert, read, seek, and such.
    122  * (For the scsi case, you might wanna speak SCSI directly to, but that can of
     122 * (For the scsi SCSCI, you might want to speak SCSI directly to, but that can of
    123123 * course be fixed - see SCSI passthru.)  So, it
    124124 * makes much sense to have a generic CD/DVD driver which implements this.
     
    136136 *
    137137 * It is possible to configure many levels of drivers inserting filters, loggers,
    138  * or whatever you desire into the chain.  We're using this for network sniffing
     138 * or whatever you desire into the chain.  We're using this for network sniffing,
    139139 * for instance.
    140140 *
    141  * The drivers are loaded in a similar manner to that of the device, namely by
     141 * The drivers are loaded in a similar manner to that of a device, namely by
    142142 * iterating a keyspace in CFGM, load the modules listed there and call
    143143 * 'VBoxDriversRegister' with a callback table.
     
    148148 * @section sec_pdm_ifs     Interfaces
    149149 *
    150  * The pluggable drivers and devices exposes one standard interface (callback
     150 * The pluggable drivers and devices expose one standard interface (callback
    151151 * table) which is used to construct, destruct, attach, detach,( ++,) and query
    152152 * other interfaces. A device will query the interfaces required for it's
     
    155155 *
    156156 * An interface here means a function table contained within the device or
    157  * driver instance data. Its method are invoked with the function table pointer
     157 * driver instance data. Its methods are invoked with the function table pointer
    158158 * as the first argument and they will calculate the address of the device or
    159159 * driver instance data from it. (This is one of the aspects which *might* have
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette