VirtualBox

Ignore:
Timestamp:
Mar 4, 2014 4:26:34 PM (11 years ago)
Author:
vboxsync
Message:

VBox/Devices/Audio: New files added as a part of audio restructuring exercise . DrvAudio.c and DrvAudioUtil.c are intermediate driver files and DrvHost* are the host backend drivers (each specific to different platform).

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DrvAudio.c

    r49765 r50680  
     1/* $Id$ */
     2/** @file
     3 * Intermedia audio driver..
     4 *
     5 * @remarks Intermediate audio driver having audio device as one of the sink and
     6 *          host backend as other..
     7 */
     8
    19/*
     10 * Copyright (C) 2006-2014 Oracle Corporation
     11 *
     12 * This file is part of VirtualBox Open Source Edition (OSE), as
     13 * available from http://www.virtualbox.org. This file is free software;
     14 * you can redistribute it and/or modify it under the terms of the GNU
     15 * General Public License (GPL) as published by the Free Software
     16 * Foundation, in version 2 as it comes in the "COPYING" file of the
     17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     18 * hope that it will be1 useful, but WITHOUT ANY WARRANTY of any kind.
     19 * --------------------------------------------------------------------
     20 *
     21 * This code is based on: audio.c from QEMU AUDIO subsystem.
     22 *
    223 * QEMU Audio subsystem
    324 *
     
    2243 * THE SOFTWARE.
    2344 */
     45
     46
    2447#define LOG_GROUP LOG_GROUP_DEV_AUDIO
    2548#include <VBox/vmm/pdm.h>
    2649#include <VBox/err.h>
    2750#include <VBox/vmm/mm.h>
     51#include <VBox/vmm/pdmaudioifs.h>
    2852
    2953#include <VBox/log.h>
     
    4165
    4266#define AUDIO_CAP "audio"
    43 #include "audio.h"
    44 #include "audio_int.h"
     67#include "DrvAudio.h"
    4568
    4669#ifdef RT_OS_WINDOWS
    4770#define strcasecmp stricmp
    4871#endif
    49 
    50 /* #define DEBUG_PLIVE */
    51 /* #define DEBUG_LIVE */
    52 /* #define DEBUG_OUT */
    53 /* #define DEBUG_CAPTURE */
    54 
    55 #define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
    56 
    57 /**
    58  * @implements PDMIAUDIOCONNECTOR
    59  */
    60 typedef struct DRVAUDIO
    61 {
    62     /** The audio interface. */
    63     PDMIAUDIOCONNECTOR      IAudioConnector;
    64     /** Pointer to the driver instance. */
    65     PPDMDRVINS              pDrvIns;
    66 } DRVAUDIO, *PDRVAUDIO;
    6772
    6873static struct audio_driver *drvtab[] = {
     
    98103};
    99104
     105extern t_sample *convAudio;
     106extern f_sample *clipAudio;
     107
     108extern t_sample *convAudioIn;
     109extern f_sample *clipAudioIn;
    100110static char *audio_streamname;
    101111
     
    104114    return audio_streamname;
    105115}
    106 
    107 struct fixed_settings {
    108     int enabled;
    109     int nb_voices;
    110     int greedy;
    111     audsettings_t settings;
    112 };
    113 
    114 static struct {
    115     struct fixed_settings fixed_out;
    116     struct fixed_settings fixed_in;
    117     union {
    118         int hz;
    119         int64_t ticks;
    120     } period;
    121     int plive;
    122 } conf = {
    123     {                           /* DAC fixed settings */
    124         1,                      /* enabled */
    125         1,                      /* nb_voices */
    126         1,                      /* greedy */
    127         {
    128             44100,              /* freq */
    129             2,                  /* nchannels */
    130             AUD_FMT_S16         /* fmt */
    131         }
    132     },
    133 
    134     {                           /* ADC fixed settings */
    135         1,                      /* enabled */
    136         1,                      /* nb_voices */
    137         1,                      /* greedy */
    138         {
    139             44100,              /* freq */
    140             2,                  /* nchannels */
    141             AUD_FMT_S16         /* fmt */
    142         }
    143     },
    144 
    145     { 200 },                    /* frequency (in Hz) */
    146     0,                          /* plive */
    147 };
    148 
    149 static AudioState glob_audio_state;
    150116
    151117volume_t nominal_volume = {
     
    165131};
    166132
    167 #ifdef VBOX
    168133volume_t sum_out_volume =
    169134{
     
    190155    INT_MAX
    191156};
    192 #endif
     157
     158
     159/***************** ring buffer Hanlding section **************/
     160static void IORingBufferCreate(PIORINGBUFFER *ppBuffer, uint32_t cSize)
     161{
     162    PIORINGBUFFER pTmpBuffer;
     163
     164    AssertPtr(ppBuffer);
     165
     166    *ppBuffer = NULL;
     167    pTmpBuffer = RTMemAllocZ(sizeof(IORINGBUFFER));
     168    if (pTmpBuffer)
     169    {
     170        pTmpBuffer->pBuffer = RTMemAlloc(cSize);
     171        if(pTmpBuffer->pBuffer)
     172        {
     173            pTmpBuffer->cBufSize = cSize;
     174            *ppBuffer = pTmpBuffer;
     175        }
     176        else
     177            RTMemFree(pTmpBuffer);
     178    }
     179}
     180
     181static void IORingBufferDestroy(PIORINGBUFFER pBuffer)
     182{
     183    if (pBuffer)
     184    {
     185        if (pBuffer->pBuffer)
     186            RTMemFree(pBuffer->pBuffer);
     187        RTMemFree(pBuffer);
     188    }
     189}
     190
     191DECL_FORCE_INLINE(void) IORingBufferReset(PIORINGBUFFER pBuffer)
     192{
     193    AssertPtr(pBuffer);
     194
     195    pBuffer->uReadPos = 0;
     196    pBuffer->uWritePos = 0;
     197    pBuffer->cBufferUsed = 0;
     198}
     199
     200DECL_FORCE_INLINE(uint32_t) IORingBufferFree(PIORINGBUFFER pBuffer)
     201{
     202    AssertPtr(pBuffer);
     203    return pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed);
     204}
     205
     206DECL_FORCE_INLINE(uint32_t) IORingBufferUsed(PIORINGBUFFER pBuffer)
     207{
     208    AssertPtr(pBuffer);
     209    return ASMAtomicReadU32(&pBuffer->cBufferUsed);
     210}
     211
     212DECL_FORCE_INLINE(uint32_t) IORingBufferSize(PIORINGBUFFER pBuffer)
     213{
     214    AssertPtr(pBuffer);
     215    return pBuffer->cBufSize;
     216}
     217
     218static void IORingBufferAquireReadBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize)
     219{
     220    uint32_t uUsed = 0;
     221    uint32_t uSize = 0;
     222
     223    AssertPtr(pBuffer);
     224
     225    *ppStart = 0;
     226    *pcSize = 0;
     227
     228    /* How much is in use? */
     229    uUsed = ASMAtomicReadU32(&pBuffer->cBufferUsed);
     230    if (uUsed > 0)
     231    {
     232        /* Get the size out of the requested size, the read block till the end
     233         * of the buffer & the currently used size. */
     234        uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uReadPos, uUsed));
     235        if (uSize > 0)
     236        {
     237            /* Return the pointer address which point to the current read
     238             * position. */
     239            *ppStart = pBuffer->pBuffer + pBuffer->uReadPos;
     240            *pcSize = uSize;
     241        }
     242    }
     243}
     244
     245DECL_FORCE_INLINE(void) IORingBufferReleaseReadBlock(PIORINGBUFFER pBuffer, uint32_t cSize)
     246{
     247    AssertPtr(pBuffer);
     248
     249    /* Split at the end of the buffer. */
     250    pBuffer->uReadPos = (pBuffer->uReadPos + cSize) % pBuffer->cBufSize;
     251    ASMAtomicSubU32(&pBuffer->cBufferUsed, cSize);
     252}
     253
     254static void IORingBufferAquireWriteBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize)
     255{
     256    uint32_t uFree;
     257    uint32_t uSize;
     258
     259    AssertPtr(pBuffer);
     260
     261    *ppStart = 0;
     262    *pcSize = 0;
     263
     264    /* How much is free? */
     265    uFree = pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed);
     266    if (uFree > 0)
     267    {
     268        /* Get the size out of the requested size, the write block till the end
     269         * of the buffer & the currently free size. */
     270        uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uWritePos, uFree));
     271        if (uSize > 0)
     272        {
     273            /* Return the pointer address which point to the current write
     274             * position. */
     275            *ppStart = pBuffer->pBuffer + pBuffer->uWritePos;
     276            *pcSize = uSize;
     277        }
     278    }
     279}
     280
     281DECL_FORCE_INLINE(void) IORingBufferReleaseWriteBlock(PIORINGBUFFER pBuffer, uint32_t cSize)
     282{
     283    AssertPtr(pBuffer);
     284
     285    /* Split at the end of the buffer. */
     286    pBuffer->uWritePos = (pBuffer->uWritePos + cSize) % pBuffer->cBufSize;
     287
     288    ASMAtomicAddU32(&pBuffer->cBufferUsed, cSize);
     289}
     290
     291/****************** Ring Buffer Function Ends *****************/
    193292
    194293/* http://www.df.lth.se/~john_e/gems/gem002d.html */
     
    203302    return u;
    204303}
    205 
    206304uint32_t lsbindex (uint32_t u)
    207305{
    208306    return popcount ((u&-u)-1);
    209307}
    210 
    211308uint64_t audio_get_clock (void)
    212309{
    213     AudioState *s;
    214 
    215     s = &glob_audio_state;
    216     return PDMDrvHlpTMGetVirtualTime (s->pDrvIns);
    217 }
    218 
     310    return PDMDrvHlpTMGetVirtualTime (gpDrvIns);
     311}
    219312uint64_t audio_get_ticks_per_sec (void)
    220313{
    221     AudioState *s;
    222 
    223     s = &glob_audio_state;
    224     return PDMDrvHlpTMGetVirtualFreq (s->pDrvIns);
    225 }
    226 
    227 #ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
    228 #error No its not
    229 #else
    230 int audio_bug (const char *funcname, int cond)
    231 {
    232     if (cond) {
    233         static int shown;
    234 
    235         AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
    236         if (!shown) {
    237             shown = 1;
    238             AUD_log (NULL, "Save all your work and restart without audio\n");
    239             AUD_log (NULL, "Please send a bug, see www.virtualbox.org\n");
    240             AUD_log (NULL, "I am sorry\n");
    241         }
    242         AUD_log (NULL, "Context:\n");
    243 
    244 #if defined AUDIO_BREAKPOINT_ON_BUG
    245 #  if defined HOST_I386
    246 #    if defined __GNUC__
    247         __asm__ ("int3");
    248 #    elif defined _MSC_VER
    249         _asm _emit 0xcc;
    250 #    else
    251         abort ();
    252 #    endif
    253 #  else
    254         abort ();
    255 #  endif
    256 #endif
    257     }
    258 
    259     return cond;
    260 }
    261 #endif
    262 
    263 static inline int audio_bits_to_index (int bits)
     314    return PDMDrvHlpTMGetVirtualFreq (gpDrvIns);
     315}
     316
     317inline int audio_bits_to_index (int bits)
    264318{
    265319    switch (bits) {
     
    274328
    275329    default:
    276         audio_bug ("bits_to_index", 1);
    277         AUD_log (NULL, "invalid bits %d\n", bits);
     330        LogFlow(("invalid bits %d\n", bits));
    278331        return 0;
    279332    }
    280 }
    281 
    282 void *audio_calloc (const char *funcname, int nmemb, size_t size)
    283 {
    284     int cond;
    285     size_t len;
    286 
    287     len = nmemb * size;
    288     cond = !nmemb || !size;
    289     cond |= nmemb < 0;
    290     cond |= len < size;
    291 
    292     if (audio_bug ("audio_calloc", cond)) {
    293         AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
    294                  funcname);
    295         AUD_log (NULL, "nmemb=%d size=%" FMTZ "u (len=%" FMTZ "u)\n",
    296                  nmemb, size, len);
    297         return NULL;
    298     }
    299 
    300     return qemu_mallocz (len);
    301333}
    302334
     
    323355    }
    324356
    325     dolog ("Bogus audfmt %d returning S16\n", fmt);
     357    LogFlow(("Bogus audfmt %d returning S16\n", fmt));
    326358    return "S16";
    327359}
    328360
    329 static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval,
    330                                         int *defaultp)
     361static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, int *defaultp)
    331362{
    332363    if (!strcasecmp (s, "u8")) {
     
    355386    }
    356387    else {
    357         dolog ("Bogus audio format `%s' using %s\n",
    358                s, audio_audfmt_to_string (defval));
     388        LogFlow(("Bogus audio format `%s' using %s\n",
     389                  s, audio_audfmt_to_string (defval)));
    359390        *defaultp = 1;
    360391        return defval;
     
    362393}
    363394
    364 static audfmt_e audio_get_conf_fmt (PCFGMNODE pCfgHandle, const char *envname,
    365                                     audfmt_e defval,
    366                                     int *defaultp)
     395static audfmt_e drvAudioGetConfFormat(PCFGMNODE pCfgHandle, const char *envname, audfmt_e defval, int *defaultp)
    367396{
    368397    char *var = NULL;
     
    382411}
    383412
    384 static int audio_get_conf_int (PCFGMNODE pCfgHandle, const char *key, int defval, int *defaultp)
     413static int drvAudioGetConfInt(PCFGMNODE pCfgHandle, const char *key, int defval, int *defaultp)
    385414{
    386415    int rc;
     
    407436}
    408437
    409 static const char *audio_get_conf_str (PCFGMNODE  pCfgHandle, const char *key,
    410                                        const char *defval,
    411                                        int *defaultp)
     438static const char *drvAudioGetConfStr(PCFGMNODE  pCfgHandle, const char *key, const char *defval, int *defaultp)
    412439{
    413440    char *val = NULL;
     
    429456}
    430457
    431 void AUD_vlog (const char *cap, const char *fmt, va_list va)
    432 {
    433     va_list va2;
    434     va_copy (va2, va); /* Have to make a copy here or GCC will break. */
    435     if (cap) {
    436         Log (("%s: %N", cap, fmt, &va2));
    437     }
    438     else {
    439         Log (("%N", fmt, &va2));
    440     }
    441     va_end (va2);
    442 }
    443 
    444 void AUD_log (const char *cap, const char *fmt, ...)
    445 {
    446     va_list va;
    447 
    448     va_start (va, fmt);
    449     AUD_vlog (cap, fmt, va);
    450     va_end (va);
    451 }
    452 
    453 static void audio_process_options (PCFGMNODE pCfgHandle, const char *prefix,
    454                                    struct audio_option *opt)
     458static void drvAudioProcessOptions(PCFGMNODE pCfgHandle, const char *prefix, struct audio_option *opt)
    455459{
    456460    int def;
     
    458462    PCFGMNODE pCfgChildChildHandle = NULL;
    459463
    460     if (audio_bug (AUDIO_FUNC, !prefix)) {
    461         dolog ("prefix = NULL\n");
    462         return;
    463     }
    464 
    465     if (audio_bug (AUDIO_FUNC, !opt)) {
    466         dolog ("opt = NULL\n");
     464    if (!prefix || !opt)
     465    {
     466        LogFlow(("prefix = NULL OR opt = NULL\n"));
    467467        return;
    468468    }
     
    471471    * The getter function will return default values.
    472472    */
    473    if(pCfgHandle != NULL) {
     473    if(pCfgHandle != NULL)
     474    {
    474475       /* If its audio general setting, need to traverse to one child node.
    475476        * /Devices/ichac97/0/LUN#0/Config/Audio
     
    499500
    500501    for (; opt->name; opt++) {
     502            LogFlow(("Option value pointer for `%s' is not set\n",
     503                   opt->name));
    501504        if (!opt->valp) {
    502             dolog ("Option value pointer for `%s' is not set\n",
    503                    opt->name);
     505            LogFlow(("Option value pointer for `%s' is not set\n",
     506                   opt->name));
    504507            continue;
    505508        }
     
    510513            {
    511514                int *intp = opt->valp;
    512                 *intp =   audio_get_conf_int(pCfgHandle, opt->name, *intp, &def);
     515                *intp =   drvAudioGetConfInt(pCfgHandle, opt->name, *intp, &def);
    513516            }
    514517            break;
     
    517520            {
    518521                audfmt_e *fmtp = opt->valp;
    519                 *fmtp = audio_get_conf_fmt (pCfgHandle, opt->name, *fmtp, &def);
     522                *fmtp = drvAudioGetConfFormat(pCfgHandle, opt->name, *fmtp, &def);
    520523            }
    521524            break;
     
    524527            {
    525528                const char **strp = opt->valp;
    526                 *strp = audio_get_conf_str (pCfgHandle, opt->name, *strp, &def);
     529                *strp = drvAudioGetConfStr(pCfgHandle, opt->name, *strp, &def);
    527530            }
    528531            break;
    529532
    530533        default:
    531             dolog ("Bad value tag for option `%s' - %d\n",
    532                    opt->name, opt->tag);
     534            LogFlow(("Bad value tag for option `%s' - %d\n",
     535                   opt->name, opt->tag));
    533536            break;
    534537        }
     
    541544}
    542545
    543 static void audio_print_settings (audsettings_t *as)
    544 {
    545     dolog ("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels);
     546static void drvAudioPrintSettings(audsettings_t *as)
     547{
     548    LogFlow(("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels));
    546549
    547550    switch (as->fmt) {
    548551    case AUD_FMT_S8:
    549         AUD_log (NULL, "S8");
     552        LogFlow(("S8\n"));
    550553        break;
    551554    case AUD_FMT_U8:
    552         AUD_log (NULL, "U8");
     555        LogFlow(("U8\n"));
    553556        break;
    554557    case AUD_FMT_S16:
    555         AUD_log (NULL, "S16");
     558        LogFlow(("S16\n"));
    556559        break;
    557560    case AUD_FMT_U16:
    558         AUD_log (NULL, "U16");
     561        LogFlow(("U16\n"));
    559562        break;
    560563    case AUD_FMT_S32:
    561         AUD_log (NULL, "S32");
     564        LogFlow(("S32\n"));
    562565        break;
    563566    case AUD_FMT_U32:
    564         AUD_log (NULL, "U32");
     567        LogFlow(("U32\n"));
    565568        break;
    566569    default:
    567         AUD_log (NULL, "invalid(%d)", as->fmt);
     570        LogFlow(("invalid(%d)\n", as->fmt));
    568571        break;
    569572    }
    570573
    571     AUD_log (NULL, " endianness=");
    572     switch (as->endianness) {
     574    LogFlow(("endianness=\n"));
     575    switch (as->endianness)
     576    {
    573577    case 0:
    574         AUD_log (NULL, "little");
     578        LogFlow(("little\n"));
    575579        break;
    576580    case 1:
    577         AUD_log (NULL, "big");
     581        LogFlow(("big\n"));
    578582        break;
    579583    default:
    580         AUD_log (NULL, "invalid");
     584        LogFlow(("invalid\n"));
    581585        break;
    582586    }
    583     AUD_log (NULL, "\n");
    584 }
    585 
    586 static int audio_validate_settings (audsettings_t *as)
     587}
     588
     589static int drvAudioValidateSettings(audsettings_t *as)
    587590{
    588591    int invalid;
     
    608611}
    609612
    610 static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as)
     613int drvAudioPcmInfoEq(PDMPCMPROPERTIES * pProps, audsettings_t *as)
    611614{
    612615    int bits = 8, sign = 0;
     
    630633        break;
    631634    }
    632     return info->freq == as->freq
    633         && info->nchannels == as->nchannels
    634         && info->sign == sign
    635         && info->bits == bits
    636         && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
    637 }
    638 
    639 void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as)
     635    return pProps->uFrequency == as->freq
     636        && pProps->cChannels == as->nchannels
     637        && pProps->fSigned == sign
     638        && pProps->cBits == bits
     639        && pProps->fSwapEndian == (as->endianness != AUDIO_HOST_ENDIANNESS);
     640}
     641
     642void drvAudioPcmInitInfo(PDMPCMPROPERTIES * pProps, audsettings_t *as)
    640643{
    641644    int bits = 8, sign = 0, shift = 0;
     
    662665    }
    663666
    664     info->freq = as->freq;
    665     info->bits = bits;
    666     info->sign = sign;
    667     info->nchannels = as->nchannels;
    668     info->shift = (as->nchannels == 2) + shift;
    669     info->align = (1 << info->shift) - 1;
    670     info->bytes_per_second = info->freq << info->shift;
    671     info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
     667    pProps->uFrequency = as->freq;
     668    pProps->cBits = bits;
     669    pProps->fSigned = sign;
     670    pProps->cChannels = as->nchannels;
     671    pProps->cShift = (as->nchannels == 2) + shift;
     672    pProps->fAlign = (1 << pProps->cShift) - 1;
     673    pProps->cbPerSec = pProps->uFrequency << pProps->cShift;
     674    pProps->fSwapEndian = (as->endianness != AUDIO_HOST_ENDIANNESS);
    672675}
    673676
     
    722725
    723726        default:
    724             AUD_log (NULL, "audio_pcm_info_clear_buf: invalid bits %d\n",
    725                      info->bits);
     727            LogFlow(("audio_pcm_info_clear_buf: invalid bits %d\n", info->bits));
    726728            break;
    727729        }
     
    732734 * Capture
    733735 */
    734 static void noop_conv (st_sample_t *dst, const void *src,
    735                        int samples, volume_t *vol)
     736static void noop_conv (st_sample_t *dst, const void *src, int samples, volume_t *vol)
    736737{
    737738    (void) src;
     
    741742}
    742743
    743 static CaptureVoiceOut *audio_pcm_capture_find_specific (
    744     AudioState *s,
    745     audsettings_t *as
    746     )
    747 {
    748     CaptureVoiceOut *cap;
    749 
    750     for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
    751         if (audio_pcm_info_eq (&cap->hw.info, as)) {
    752             return cap;
    753         }
    754     }
    755     return NULL;
    756 }
    757 
    758 static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
    759 {
    760     struct capture_callback *cb;
    761 
    762 #ifdef DEBUG_CAPTURE
    763     dolog ("notification %d sent\n", cmd);
    764 #endif
    765     for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
    766         cb->ops.notify (cb->opaque, cmd);
    767     }
    768 }
    769 
    770744static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
    771745{
    772     if (cap->hw.enabled != enabled) {
     746    if (cap->hw.fEnabled != enabled)
     747    {
    773748        audcnotification_e cmd;
    774         cap->hw.enabled = enabled;
     749        cap->hw.fEnabled = enabled;
    775750        cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
    776         audio_notify_capture (cap, cmd);
    777     }
    778 }
    779 
    780 static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
    781 {
    782     HWVoiceOut *hw = &cap->hw;
    783     SWVoiceOut *sw;
     751    }
     752}
     753
     754static void drvAudioRecalcAndNotifyCapture(CaptureVoiceOut *cap)
     755{
     756    PPDMHOSTVOICEOUT hw = &cap->hw;
     757    PPDMGSTVOICEOUT sw;
     758    PPDMGSTVOICEOUT pIter;
    784759    int enabled = 0;
    785 
    786     for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
    787         if (sw->active) {
     760    LogFlow(("drvAudioRecalcAndNotifyCaptuer \n"));
     761
     762    RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut)
     763    {
     764        sw = pIter;
     765        LogFlow(("1\n"));
     766        if (sw->State.fActive) {
    788767            enabled = 1;
    789768            break;
     
    793772}
    794773
    795 static void audio_detach_capture (HWVoiceOut *hw)
    796 {
    797     SWVoiceCap *sc = hw->cap_head.lh_first;
    798 
    799     while (sc) {
    800         SWVoiceCap *sc1 = sc->entries.le_next;
    801         SWVoiceOut *sw = &sc->sw;
     774void drvAudioDetachCapture(PPDMHOSTVOICEOUT pHostVoiceOut)
     775{
     776    SWVoiceCap * sc;
     777    SWVoiceCap *pIter;
     778    LogFlow(("drvAudioDetachCapture \n"));
     779    RTListForEach(&pHostVoiceOut->HeadCapturedVoice, pIter, SWVoiceCap, ListCapturedVoice)
     780    {
     781        sc = pIter;
     782        PPDMGSTVOICEOUT sw = &sc->sw;
    802783        CaptureVoiceOut *cap = sc->cap;
    803         int was_active = sw->active;
    804 
    805         if (sw->rate) {
    806             st_rate_stop (sw->rate);
    807             sw->rate = NULL;
    808         }
    809 
    810         LIST_REMOVE (sw, entries);
    811         LIST_REMOVE (sc, entries);
    812         qemu_free (sc);
     784        int was_active = sw->State.fActive;
     785
     786        if (sw->State.rate) {
     787            st_rate_stop (sw->State.rate);
     788            sw->State.rate = NULL;
     789        }
     790
     791        while (!RTListIsEmpty(&sw->ListGstVoiceOut))
     792        {
     793            PPDMGSTVOICEOUT pIterTmp = RTListGetFirst(&sw->ListGstVoiceOut, PDMGSTVOICEOUT, ListGstVoiceOut);
     794            RTListNodeRemove(&pIterTmp->ListGstVoiceOut);
     795        }
     796
     797        while (!RTListIsEmpty(&sc->ListCapturedVoice))
     798        {
     799            SWVoiceCap * pIterTmp = RTListGetFirst(&sc->ListCapturedVoice, SWVoiceCap, ListCapturedVoice);
     800            RTListNodeRemove(&pIterTmp->ListCapturedVoice);
     801        }
     802
    813803        if (was_active) {
    814804            /* We have removed soft voice from the capture:
    815805               this might have changed the overall status of the capture
    816806               since this might have been the only active voice */
    817             audio_recalc_and_notify_capture (cap);
    818         }
    819         sc = sc1;
    820     }
    821 }
    822 
    823 static int audio_attach_capture (AudioState *s, HWVoiceOut *hw)
     807            drvAudioRecalcAndNotifyCapture(cap);
     808        }
     809    }
     810}
     811
     812int drvAudioAttachCapture(PDRVAUDIO pDrvAudio, PPDMHOSTVOICEOUT pHostVoiceOut)
    824813{
    825814    CaptureVoiceOut *cap;
    826 
    827     audio_detach_capture (hw);
    828     for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
     815    CaptureVoiceOut *pIter;
     816
     817    drvAudioDetachCapture(pHostVoiceOut);
     818    RTListForEach(&pDrvAudio->HeadCapturedVoice, pIter, CaptureVoiceOut, ListCapturedVoice)
     819    {
    829820        SWVoiceCap *sc;
    830         SWVoiceOut *sw;
    831         HWVoiceOut *hw_cap = &cap->hw;
    832 
    833         sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
    834         if (!sc) {
    835             dolog ("Could not allocate soft capture voice (%u bytes)\n",
    836                    sizeof (*sc));
     821        PPDMGSTVOICEOUT pGstVoiceOut;
     822        cap = pIter;
     823        PPDMHOSTVOICEOUT hw_cap = &cap->hw;
     824        sc = (SWVoiceCap*) RTMemAllocZ(1 * sizeof (SWVoiceCap));
     825        if (!sc)
     826        {
     827            LogFlow(("Could not allocate soft capture voice (%u bytes)\n",
     828                   sizeof (*sc)));
    837829            return -1;
    838830        }
    839831
    840832        sc->cap = cap;
    841         sw = &sc->sw;
    842         sw->hw = hw_cap;
    843         sw->info = hw->info;
    844         sw->empty = 1;
    845         sw->active = hw->enabled;
    846         sw->conv = noop_conv;
    847         sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
    848         sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
    849         if (!sw->rate) {
    850             dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
    851             qemu_free (sw);
     833        pGstVoiceOut = &sc->sw;
     834        pGstVoiceOut->pHostVoiceOut = hw_cap;
     835        pGstVoiceOut->Props = pHostVoiceOut->Props;
     836        pGstVoiceOut->State.fEmpty = 1;
     837        pGstVoiceOut->State.fActive = pHostVoiceOut->fEnabled;
     838        LogFlow(("DrvAudio: setting gstvoiceout ratio. Freq=%d and Frew=%d",
     839                 hw_cap->Props.uFrequency,  pGstVoiceOut->Props.uFrequency ));
     840        pGstVoiceOut->State.ratio = ((int64_t) hw_cap->Props.uFrequency << 32) / pGstVoiceOut->Props.uFrequency;
     841        pGstVoiceOut->State.rate = st_rate_start (pGstVoiceOut->Props.uFrequency, hw_cap->Props.uFrequency);
     842        if (!pGstVoiceOut->State.rate)
     843        {
     844            LogFlow(("Error Could not start rate conversion \n"));
     845            RTMemFree(pGstVoiceOut);
    852846            return -1;
    853847        }
    854         LIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
    855         LIST_INSERT_HEAD (&hw->cap_head, sc, entries);
    856 #ifdef DEBUG_CAPTURE
    857         asprintf (&sw->name, "for %p %d,%d,%d",
    858                   hw, sw->info.freq, sw->info.bits, sw->info.nchannels);
    859         dolog ("Added %s active = %d\n", sw->name, sw->active);
    860 #endif
    861         if (sw->active) {
     848        RTListPrepend(&hw_cap->HeadGstVoiceOut, &pGstVoiceOut->ListGstVoiceOut);
     849        RTListPrepend(&pHostVoiceOut->HeadCapturedVoice, &sc->ListCapturedVoice);
     850        if (pGstVoiceOut->State.fActive)
     851        {
    862852            audio_capture_maybe_changed (cap, 1);
    863853        }
     
    869859 * Hard voice (capture)
    870860 */
    871 static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
    872 {
    873     SWVoiceIn *sw;
    874     int m = hw->total_samples_captured;
    875 
    876     for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
    877         if (sw->active) {
    878             m = audio_MIN (m, sw->total_hw_samples_acquired);
     861static int audio_pcm_hw_find_min_in (PPDMHOSTVOICEIN hw)
     862{
     863    PPDMGSTVOICEIN pIter = NULL;
     864    PPDMGSTVOICEIN pGstVoiceIn = NULL;
     865    int m = hw->cSamplesCaptured;
     866
     867    RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn)
     868    {
     869        pGstVoiceIn = pIter;
     870        LogFlow(("DrvAudio: pGstVioceIn = %p\n", pGstVoiceIn));
     871        if (pGstVoiceIn->State.fActive)
     872        {
     873            m = audio_MIN (m, pGstVoiceIn->cHostSamplesAcquired);
    879874        }
    880875    }
     
    882877}
    883878
    884 int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
    885 {
    886     int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
    887     if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
    888         dolog ("live=%d hw->samples=%d\n", live, hw->samples);
     879int audio_pcm_hw_get_live_in (PPDMHOSTVOICEIN hw)
     880{
     881    int live = hw->cSamplesCaptured - audio_pcm_hw_find_min_in (hw);
     882    if (live < 0 || live > hw->cSamples)
     883    {
     884        LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
    889885        return 0;
    890886    }
     
    895891 * Soft voice (capture)
    896892 */
    897 static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
    898 {
    899     HWVoiceIn *hw = sw->hw;
    900     int live = hw->total_samples_captured - sw->total_hw_samples_acquired;
     893static int audio_pcm_sw_get_rpos_in (PPDMGSTVOICEIN sw)
     894{
     895    PPDMHOSTVOICEIN hw = sw->hw;
     896    int live = hw->cSamplesCaptured - sw->cHostSamplesAcquired;
    901897    int rpos;
    902898
    903     if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
    904         dolog ("live=%d hw->samples=%d\n", live, hw->samples);
     899    if (live < 0 || live > hw->cSamples)
     900    {
     901        LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
    905902        return 0;
    906903    }
    907904
    908     rpos = hw->wpos - live;
     905    rpos = hw->offWrite - live;
    909906    if (rpos >= 0) {
    910907        return rpos;
    911908    }
    912909    else {
    913         return hw->samples + rpos;
    914     }
    915 }
    916 
    917 int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
    918 {
    919     HWVoiceIn *hw = sw->hw;
     910        return hw->cSamples + rpos;
     911    }
     912}
     913
     914int audio_pcm_sw_read (PDRVAUDIO pThis, PPDMGSTVOICEIN sw, PPDMHOSTSTEREOSAMPLE buf, int size)
     915{
     916    PPDMHOSTVOICEIN hw = sw->hw;
    920917    int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
    921     st_sample_t *src, *dst = sw->buf;
    922 
    923     rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;
    924 
    925     live = hw->total_samples_captured - sw->total_hw_samples_acquired;
    926     if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
    927         dolog ("live_in=%d hw->samples=%d\n", live, hw->samples);
     918    PPDMHOSTSTEREOSAMPLE src, dst = sw->buf;
     919    PPDMHOSTSTEREOSAMPLE tmp = sw->buf;
     920    PPDMHOSTSTEREOSAMPLE pSampleBuf;
     921    char *pcDst = NULL;
     922    char *pcSrc = NULL;
     923    uint32_t cbToWrite;
     924    uint32_t csAvail = 0;
     925    uint32_t cSamplesRead = 0;
     926    uint32_t cbToRead = 0;
     927    uint32_t csWritten = 0;
     928    uint32_t cSamplesInRingBuffer = 0;
     929    uint32_t csToWrite;
     930    uint32_t csLimit;
     931
     932    /* Max capacity to hold 1000 PDMHOSTSTERESAMPLE type samples. */
     933    pSampleBuf = (PPDMHOSTSTEREOSAMPLE) RTMemAlloc(1000 * sizeof(PDMHOSTSTEREOSAMPLE));
     934    rpos = audio_pcm_sw_get_rpos_in (sw) % hw->cSamples;
     935
     936    /* difference between how many samples have be captured/read by the host and how
     937     * many have been transferred to guest (guest physical memory) to be utilized by the guest
     938     * eg skype on guest or saving samples in file in guest.
     939     */
     940    live = hw->cSamplesCaptured - sw->cHostSamplesAcquired;
     941    if (live < 0 || live > hw->cSamples)
     942    {
     943        LogFlow(("Error: live_in=%d hw->samples=%d\n", live, hw->cSamples));
    928944        return 0;
    929945    }
    930946
    931     samples = size >> sw->info.shift;
    932     if (!live) {
     947    samples = size >> sw->Props.cShift;
     948    if (!live)
     949    {
     950        LogFlow(("DrvAudio: Error: No Live data \n"));
    933951        return 0;
    934952    }
    935953
    936     swlim = (live * sw->ratio) >> 32;
     954    swlim = (live * sw->State.ratio) >> 32;
     955    csLimit = swlim;
    937956    swlim = audio_MIN (swlim, samples);
    938 
    939     while (swlim) {
    940         src = hw->conv_buf + rpos;
    941         isamp = hw->wpos - rpos;
     957    while (swlim)
     958    {
     959        src = hw->pConversionBuf + rpos;
     960        isamp = hw->offWrite - rpos;
    942961        /* XXX: <= ? */
    943         if (isamp <= 0) {
    944             isamp = hw->samples - rpos;
    945         }
    946 
    947         if (!isamp) {
     962        if (isamp <= 0)
     963            isamp = hw->cSamples - rpos;
     964
     965        if (!isamp)
    948966            break;
    949         }
     967
    950968        osamp = swlim;
    951 
    952         if (audio_bug (AUDIO_FUNC, osamp < 0)) {
    953             dolog ("osamp=%d\n", osamp);
     969        if (osamp < 0)
     970        {
     971            LogFlow(("Error: osamp=%d\n", osamp));
    954972            return 0;
    955973        }
     
    958976            Log(("audio_pcm_sw_read: buffer overflow!! ret = %d, osamp = %d, buf_samples = %d\n",
    959977                  ret, osamp, sw->buf_samples));
    960         st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
     978        st_rate_flow (sw->State.rate, src, dst, &isamp, &osamp);
    961979        swlim -= osamp;
    962         rpos = (rpos + isamp) % hw->samples;
     980        rpos = (rpos + isamp) % hw->cSamples;
    963981        dst += osamp;
    964982        ret += osamp;
    965983        total += isamp;
    966984    }
    967 
    968     if (ret > sw->buf_samples)
    969         Log(("audio_pcm_sw_read: buffer overflow!! ret = %d, buf_samples = %d\n", ret, sw->buf_samples));
    970     sw->clip (buf, sw->buf, ret);
    971     sw->total_hw_samples_acquired += total;
    972     return ret << sw->info.shift;
     985    sw->cHostSamplesAcquired = sw->cHostSamplesAcquired + total;
     986    if (csLimit >= samples)
     987    {
     988        /* read audio that is there in the ring buffer */
     989        cSamplesInRingBuffer = IORingBufferUsed(pThis->pAudioReadBuf) / sizeof(PDMHOSTSTEREOSAMPLE);
     990        if (cSamplesInRingBuffer >= 45000) /* 750 K Buffer / sizeof(PDMHOSTSTEREOSAMPLE)*/
     991        {
     992            IORingBufferReset(pThis->pAudioReadBuf);
     993            cSamplesInRingBuffer = 0;
     994        }
     995        if (cSamplesInRingBuffer > samples)
     996            cSamplesInRingBuffer = samples;
     997        cSamplesRead = 0, cbToRead = 0;
     998        while (cSamplesRead < cSamplesInRingBuffer)
     999        {
     1000            cbToRead = cSamplesInRingBuffer * sizeof(PDMHOSTSTEREOSAMPLE);
     1001            IORingBufferAquireReadBlock(pThis->pAudioReadBuf, cbToRead,
     1002                                         &pcSrc, &cbToRead);
     1003            if (!cbToRead)
     1004                LogFlow(("DrvAudio: There are no audio in queue to be written. \n"));
     1005            memcpy((uint8_t *)pSampleBuf, pcSrc, cbToRead);
     1006            cSamplesRead = cSamplesRead + (cbToRead / sizeof(PDMHOSTSTEREOSAMPLE));
     1007            /* Release the read buffer, so it could be used for new data. */
     1008            IORingBufferReleaseReadBlock(pThis->pAudioReadBuf, cbToRead);
     1009        }
     1010        memcpy((uint8_t *)pSampleBuf + cbToRead, (uint8_t *)sw->buf,
     1011               (samples - cSamplesRead) * sizeof(PDMHOSTSTEREOSAMPLE));
     1012
     1013        memcpy((uint8_t *)buf, (uint8_t *)pSampleBuf, samples * sizeof(PDMHOSTSTEREOSAMPLE));
     1014
     1015        csToWrite = ret - (samples - cSamplesRead);
     1016        csAvail = IORingBufferFree(pThis->pAudioReadBuf) / sizeof(PDMHOSTSTEREOSAMPLE);
     1017        csWritten = 0;
     1018        while (csWritten < csToWrite)
     1019        {
     1020            cbToWrite = csToWrite * sizeof(PDMHOSTSTEREOSAMPLE);
     1021            IORingBufferAquireWriteBlock(pThis->pAudioReadBuf, cbToWrite, &pcDst, &cbToWrite);
     1022
     1023            csToWrite = cbToWrite / sizeof(PDMHOSTSTEREOSAMPLE);
     1024            if (RT_UNLIKELY(csToWrite == 0))
     1025            {
     1026                IORingBufferReleaseWriteBlock(pThis->pAudioReadBuf, cbToWrite);
     1027                IORingBufferReset(pThis->pAudioReadBuf);
     1028                LogFlow(("DrvAudio: NO space in Ring buffer. Not doing anything, just discarding samples.\n"));
     1029            }
     1030
     1031            /* copy the audio data not accepted by the backend to the ring buffer */
     1032            memcpy(pcDst, (uint8_t*)sw->buf + ((samples - cSamplesRead) * sizeof(PDMHOSTSTEREOSAMPLE)) +
     1033                   (csWritten * sizeof(PDMHOSTSTEREOSAMPLE)), cbToWrite);
     1034            IORingBufferReleaseWriteBlock(pThis->pAudioReadBuf, cbToWrite);
     1035            csWritten += csToWrite;
     1036        }
     1037        return samples << sw->Props.cShift;
     1038    }
     1039    else if (csLimit < samples && csLimit != 0)
     1040    {
     1041        csAvail = IORingBufferFree(pThis->pAudioReadBuf) / sizeof(PDMHOSTSTEREOSAMPLE);
     1042        csWritten = 0;
     1043        while (csWritten < ret)
     1044        {
     1045            csToWrite = ret - csWritten;
     1046            cbToWrite = csToWrite * sizeof(PDMHOSTSTEREOSAMPLE);
     1047            IORingBufferAquireWriteBlock(pThis->pAudioReadBuf, cbToWrite, &pcDst, &cbToWrite);
     1048
     1049            csToWrite = cbToWrite / sizeof(PDMHOSTSTEREOSAMPLE);
     1050            if (RT_UNLIKELY(csToWrite == 0))
     1051                LogFlow(("DrvAudio: NO space in Ring buffer. Not doing anything, just discarding samples.\n"));
     1052
     1053            /* copy the audio data not accepted by the backend to the ring buffer */
     1054            memcpy(pcDst, (uint8_t*)sw->buf + (csWritten * sizeof(PDMHOSTSTEREOSAMPLE)), cbToWrite);
     1055            IORingBufferReleaseWriteBlock(pThis->pAudioReadBuf, cbToWrite);
     1056            csWritten += csToWrite;
     1057        }
     1058        memcpy(buf, pSampleBuf, 0);
     1059        return 0;
     1060    }
     1061    return 0;
    9731062}
    9741063
     
    9761065 * Hard voice (playback)
    9771066 */
    978 static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
    979 {
    980     SWVoiceOut *sw;
     1067static int audio_pcm_hw_find_min_out (PPDMHOSTVOICEOUT hw, int *nb_livep)
     1068{
     1069    PPDMGSTVOICEOUT sw;
     1070    PPDMGSTVOICEOUT pIter;
    9811071    int m = INT_MAX;
    9821072    int nb_live = 0;
    983 
    984     for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
    985         if (sw->active || !sw->empty) {
    986             m = audio_MIN (m, sw->total_hw_samples_mixed);
     1073    LogFlow(("Hard Voice Playback \n"));
     1074
     1075    RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut)
     1076    {
     1077        sw = pIter;
     1078        if (sw->State.fActive || !sw->State.fEmpty)
     1079        {
     1080            m = audio_MIN (m, sw->cSamplesMixed);
    9871081            nb_live += 1;
    9881082        }
     
    9931087}
    9941088
    995 int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live)
     1089int audio_pcm_hw_get_live_out2 (PPDMHOSTVOICEOUT hw, int *nb_live)
    9961090{
    9971091    int smin;
     
    10021096        return 0;
    10031097    }
    1004     else {
     1098    else
     1099    {
    10051100        int live = smin;
    10061101
    1007         if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
    1008             dolog ("live=%d hw->samples=%d\n", live, hw->samples);
     1102        if (live < 0 || live > hw->cSamples)
     1103        {
     1104            LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
    10091105            return 0;
    10101106        }
     
    10131109}
    10141110
    1015 int audio_pcm_hw_get_live_out (HWVoiceOut *hw)
     1111int audio_pcm_hw_get_live_out (PPDMHOSTVOICEOUT hw)
    10161112{
    10171113    int nb_live;
     
    10191115
    10201116    live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
    1021     if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
    1022         dolog ("live=%d hw->samples=%d\n", live, hw->samples);
     1117    if (live < 0 || live > hw->cSamples)
     1118    {
     1119        LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
    10231120        return 0;
    10241121    }
     
    10261123}
    10271124
     1125#if 0
    10281126/*
    10291127 * Soft voice (playback)
    10301128 */
    1031 int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
     1129int audio_pcm_sw_write (PDRVAUDIO pThis,PPDMGSTVOICEOUT pGstVoiceOut, void *buf, int size)
    10321130{
    10331131    int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
    10341132    int ret = 0, pos = 0, total = 0;
    10351133
    1036     if (!sw) {
     1134    if (!pGstVoiceOut) {
    10371135        return size;
    10381136    }
    10391137
    1040     hwsamples = sw->hw->samples;
    1041 
    1042     live = sw->total_hw_samples_mixed;
    1043     if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){
    1044         dolog ("live=%d hw->samples=%d\n", live, hwsamples);
    1045         return 0;
     1138    hwsamples = pGstVoiceOut->pHostVoiceOut->cSamples;
     1139    LogFlow(("DrvAudio: hwSamples = %d\n", hwsamples));
     1140
     1141    live = pGstVoiceOut->cSamplesMixed;
     1142    if (live < 0 || live > hwsamples)
     1143    {
     1144        LogFlow(("Error: live=%d hw->samples=%d\n", live, hwsamples));
     1145        return size;
    10461146    }
    10471147
    10481148    if (live == hwsamples) {
    1049 #ifdef DEBUG_OUT
    1050         dolog ("%s is full %d\n", sw->name, live);
    1051 #endif
    1052         return 0;
    1053     }
    1054 
    1055     wpos = (sw->hw->rpos + live) % hwsamples;
    1056     samples = size >> sw->info.shift;
     1149        LogFlow(("DrvAudio: full %d\n", live));
     1150        return size;
     1151    }
     1152
     1153    wpos = (pGstVoiceOut->pHostVoiceOut->offRead + live) % hwsamples;
     1154    samples = size >> pGstVoiceOut->Props.cShift;
    10571155
    10581156    dead = hwsamples - live;
    1059     swlim = ((int64_t) dead << 32) / sw->ratio;
     1157    swlim = ((int64_t) dead << 32) / pGstVoiceOut->State.ratio;
    10601158    swlim = audio_MIN (swlim, samples);
    1061     if (swlim > sw->buf_samples)
     1159    if (swlim > pGstVoiceOut->cSamples)
    10621160        Log(("audio_pcm_sw_write: buffer overflow!! swlim = %d, buf_samples = %d\n",
    1063              swlim, pos, sw->buf_samples));
     1161             swlim, pos, pGstVoiceOut->cSamples));
     1162    //swlim = samples;
    10641163    if (swlim) {
    1065 #ifndef VBOX
    1066         sw->conv (sw->buf, buf, swlim, &sw->vol);
    1067 #else
    1068         sw->conv (sw->buf, buf, swlim, &sum_out_volume);
    1069 #endif
    1070     }
    1071 
    1072     while (swlim) {
     1164        convAudio (pGstVoiceOut->buf, buf, swlim, &sum_out_volume);
     1165    }
     1166
     1167    while (swlim)
     1168    {
    10731169        dead = hwsamples - live;
    10741170        left = hwsamples - wpos;
     
    10791175        isamp = swlim;
    10801176        osamp = blck;
    1081         if (pos + isamp > sw->buf_samples)
     1177        //osamp = left;
     1178        if (pos + isamp > pGstVoiceOut->cSamples)
    10821179            Log(("audio_pcm_sw_write: buffer overflow!! isamp = %d, pos = %d, buf_samples = %d\n",
    1083                  isamp, pos, sw->buf_samples));
     1180                 isamp, pos, pGstVoiceOut->cSamples));
    10841181        st_rate_flow_mix (
    1085             sw->rate,
    1086             sw->buf + pos,
    1087             sw->hw->mix_buf + wpos,
     1182            pGstVoiceOut->State.rate,
     1183            pGstVoiceOut->buf + pos,
     1184            pGstVoiceOut->pHostVoiceOut->pHostSterioSampleBuf + wpos,
    10881185            &isamp,
    10891186            &osamp
     
    10971194    }
    10981195
    1099     sw->total_hw_samples_mixed += total;
    1100     sw->empty = sw->total_hw_samples_mixed == 0;
    1101 
    1102 #ifdef DEBUG_OUT
    1103     dolog (
    1104         "%s: write size %d ret %d total sw %d\n",
    1105         SW_NAME (sw),
    1106         size >> sw->info.shift,
     1196    pGstVoiceOut->cSamplesMixed += total;
     1197    pGstVoiceOut->State.fEmpty = pGstVoiceOut->cSamplesMixed == 0;
     1198
     1199    LogFlow((
     1200        "write size %d ret %d total sw %d\n",
     1201        size >> pGstVoiceOut->Props.cShift,
    11071202        ret,
    1108         sw->total_hw_samples_mixed
    1109         );
     1203        pGstVoiceOut->cSamplesMixed
     1204        ));
     1205
     1206    //return ret << pGstVoiceOut->Props.cShift;
     1207    return size;
     1208}
    11101209#endif
    11111210
    1112     return ret << sw->info.shift;
     1211/*
     1212 * Soft voice (playback)
     1213 */
     1214int audio_pcm_sw_write(PDRVAUDIO pThis, PPDMGSTVOICEOUT pGstVoiceOut, void *buf, int size)
     1215{
     1216    int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
     1217    int ret = 0, pos = 0, total = 0;
     1218    uint8_t *pcDst = NULL;
     1219    uint8_t *pcSrc = NULL;
     1220    uint32_t cbToWrite;
     1221    uint32_t cSamplesInQueue = 0;
     1222    uint32_t cbSamplesInQueue = 0;
     1223    uint32_t cbTotalSamples = 0;
     1224    uint32_t cTotalSamples = 0;
     1225    uint32_t cSamplesAccepted = 0;
     1226    /* sample buf to hold the samples that have been passed from Device and to hold samples from the queue
     1227     * 500 KB.
     1228     */
     1229    uint8_t SampleBuf[512000];
     1230    PDMHOSTSTEREOSAMPLE pdmSampleBuf[5120];
     1231    uint32_t cSamplesLeft;
     1232
     1233    if (!pGstVoiceOut)
     1234    {
     1235        LogFlow(("DrvAudio: GstVoiceOut NULL \n"));
     1236       return size;
     1237    }
     1238    LogFlow(("DrvAudio: size to write = %d\n", size));
     1239
     1240    hwsamples = pGstVoiceOut->pHostVoiceOut->cSamples;
     1241
     1242    live = pGstVoiceOut->cSamplesMixed;
     1243    if (live < 0 || live > hwsamples)
     1244    {
     1245        /* save all the samples in the ring buffer, and return as if all the samples have been accepted.
     1246         * Saving in ring buffer as host buffer is full and can't take any more samples.
     1247         */
     1248        cbToWrite = size;
     1249        LogFlow(("DrvAudio: Error: live=%d hw->samples=%d\n", live, hwsamples));
     1250        //return 0
     1251        IORingBufferAquireWriteBlock(pThis->pAudioWriteBuf, cbToWrite, &pcDst, &cbToWrite);
     1252        if (RT_UNLIKELY(cbToWrite == 0))
     1253            LogFlow(("DrvAudio: NO space in Ring buffer. Not doing anything, just discarding samples.\n"));
     1254
     1255        /* copy the audio data not accepted by the backend to the ring buffer */
     1256        memcpy(pcDst, (uint8_t*)buf , cbToWrite);
     1257
     1258        /* Rlease the ring buffer */
     1259        IORingBufferReleaseWriteBlock(pThis->pAudioWriteBuf, cbToWrite);
     1260        return size;
     1261    }
     1262
     1263    if (live == hwsamples)
     1264    {
     1265        /* save all the samples in the ring buffer, and return as if all the samples have been accepted.
     1266         * Saving in ring buffer as host buffer is full and can't take any more samples.
     1267         */
     1268        LogFlow(("DrvAudio: full %d\n", live));
     1269        //return 0;
     1270        cbToWrite = size;
     1271        IORingBufferAquireWriteBlock(pThis->pAudioWriteBuf, cbToWrite, &pcDst, &cbToWrite);
     1272        if (RT_UNLIKELY(cbToWrite == 0))
     1273            LogFlow(("DrvAudio: NO space in Ring buffer. Not doing anything, just discarding samples.\n"));
     1274
     1275        /* copy the audio data not accepted by the backend to the ring buffer */
     1276        memcpy(pcDst, (uint8_t*)buf, cbToWrite);
     1277
     1278        /* Rlease the ring buffer */
     1279        IORingBufferReleaseWriteBlock(pThis->pAudioWriteBuf, cbToWrite);
     1280        return size;
     1281    }
     1282
     1283    wpos = (pGstVoiceOut->pHostVoiceOut->offRead + live) % hwsamples;
     1284    /* @todo check it. to convert size to num of samples */
     1285    //samples = cbTotalSamples >> pGstVoiceOut->Props.cShift;
     1286    samples = size >> pGstVoiceOut->Props.cShift;
     1287
     1288    dead = hwsamples - live;
     1289    /* swlim is upper limit of max no. of samples that can be transferred in this cycle to backend */
     1290    swlim = ((int64_t) dead << 32) / pGstVoiceOut->State.ratio;
     1291    swlim = audio_MIN (swlim, samples);
     1292
     1293    LogFlow(("DrvAudio: swlim = %d\n", swlim));
     1294
     1295    if (swlim > pGstVoiceOut->cSamples)
     1296        Log(("audio_pcm_sw_write: buffer overflow!! swlim = %d, buf_samples = %d\n",
     1297             swlim, pos, pGstVoiceOut->cSamples));
     1298    cSamplesAccepted = swlim;
     1299     /* find out how much of the queue is full. */
     1300    cbSamplesInQueue = IORingBufferUsed(pThis->pAudioWriteBuf);
     1301    /* if ring buffer hold samples > 100 KB, discard samples */
     1302    if (cbSamplesInQueue > 102400)
     1303    {
     1304        LogFlow(("DrvAudio: Samples in ring buffer > 300 KB. Discarding \n"));
     1305        cbSamplesInQueue = 0;
     1306        IORingBufferReset(pThis->pAudioWriteBuf);
     1307    }
     1308    /* read only that much samples as requried to be processed */
     1309    if (cbSamplesInQueue > (cSamplesAccepted << pGstVoiceOut->Props.cShift))
     1310        cbSamplesInQueue = (cSamplesAccepted << pGstVoiceOut->Props.cShift);
     1311
     1312    LogFlow(("DrvAudio: Samples in queue =%d and its size=%d\n",
     1313              cbSamplesInQueue >> pGstVoiceOut->Props.cShift, cbSamplesInQueue));
     1314
     1315    /* read all the samples that are there in the queue and copy them to SampleBuf .
     1316     * Reading all samples from the ring buffer as we need to send these samples first
     1317     * and then add the samples received in this iteration to the ring buffer.
     1318     */
     1319    IORingBufferAquireReadBlock(pThis->pAudioWriteBuf, cbSamplesInQueue, &pcSrc, &cbSamplesInQueue);
     1320    if (!cbSamplesInQueue)
     1321        LogFlow(("DrvAudio: There are no audio in queue to be written. \n"));
     1322
     1323
     1324    memcpy(SampleBuf, pcSrc, cbSamplesInQueue);
     1325    /* Append the buf to samples that were there in the queue. SampBuf holds all the data to transfer */
     1326    memcpy(SampleBuf + cbSamplesInQueue, buf, size);
     1327    /* Release the read buffer, so it could be used for new data. */
     1328    IORingBufferReleaseReadBlock(pThis->pAudioWriteBuf, cbSamplesInQueue);
     1329
     1330    /* reset the ring buffer to accept new data. */
     1331
     1332    /* cbTotalSamples = size of samples passed from the device + size of samples in the queue */
     1333    cbTotalSamples = size + cbSamplesInQueue;
     1334    LogFlow(("DrvAudio: size of samples read = %d and sz of samples recd = %d\n",
     1335              cbSamplesInQueue, size));
     1336    LogFlow(("DrvAudio: TotalSamples = %d\n", cbTotalSamples >> pGstVoiceOut->Props.cShift));
     1337    if (swlim) {
     1338        /* conversion engine: dest, source, num of samples, volume */
     1339        convAudio (pGstVoiceOut->buf, SampleBuf, swlim, &sum_out_volume);
     1340    }
     1341
     1342    while (swlim)
     1343    {
     1344        dead = hwsamples - live;
     1345        left = hwsamples - wpos;
     1346        blck = audio_MIN (dead, left);
     1347        if (!blck) {
     1348            break;
     1349        }
     1350        isamp = swlim;
     1351        osamp = blck;
     1352        if (pos + isamp > pGstVoiceOut->cSamples)
     1353            Log(("audio_pcm_sw_write: buffer overflow!! isamp = %d, pos = %d, buf_samples = %d\n",
     1354                 isamp, pos, pGstVoiceOut->cSamples));
     1355        /* mix and write to the host buffer to be read by the host during playout */
     1356        st_rate_flow_mix (
     1357            pGstVoiceOut->State.rate,
     1358            pGstVoiceOut->buf + pos,
     1359            pGstVoiceOut->pHostVoiceOut->pHostSterioSampleBuf + wpos,
     1360            &isamp,
     1361            &osamp
     1362            );
     1363        ret += isamp;
     1364        swlim -= isamp;
     1365        pos += isamp;
     1366        live += osamp;
     1367        wpos = (wpos + osamp) % hwsamples;
     1368        total += osamp;
     1369    }
     1370
     1371    pGstVoiceOut->cSamplesMixed += total;
     1372    pGstVoiceOut->State.fEmpty = pGstVoiceOut->cSamplesMixed == 0;
     1373
     1374    cSamplesLeft = (cbTotalSamples >>  pGstVoiceOut->Props.cShift) - cSamplesAccepted ;
     1375    LogFlow(("DrvAudio: cSamplesLeft = %d\n", cSamplesLeft));
     1376    if (cSamplesLeft > 0)
     1377    {
     1378        cbToWrite = cSamplesLeft << pGstVoiceOut->Props.cShift;
     1379        /* max capacity of ring buffer is 516196 */
     1380        //cbToWrite = audio_MIN(cbToWrite, 516196);
     1381        IORingBufferAquireWriteBlock(pThis->pAudioWriteBuf, cbToWrite, &pcDst, &cbToWrite);
     1382        if (RT_UNLIKELY(cbToWrite == 0))
     1383            LogFlow(("DrvAudio: NO space in Ring buffer. Not doing anything, just discarding samples.\n"));
     1384
     1385        /* copy the audio data not accepted by the backend to the ring buffer */
     1386        memcpy(pcDst, (uint8_t*)SampleBuf + (cSamplesAccepted << pGstVoiceOut->Props.cShift), cbToWrite);
     1387
     1388        /* Rlease the ring buffer */
     1389        IORingBufferReleaseWriteBlock(pThis->pAudioWriteBuf, cbToWrite);
     1390    }
     1391    /* convert no of samples to bytes */
     1392    return size;
    11131393}
    11141394
     
    11161396static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
    11171397{
    1118     dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
    1119            cap, info->bits, info->sign, info->freq, info->nchannels);
     1398    LogFlow(("%s: bits %d, sign %d, freq %d, nchan %d\n",
     1399           cap, info->bits, info->sign, info->freq, info->nchannels));
    11201400}
    11211401#endif
    11221402
    1123 #define DAC
    1124 #include "audio_template.h"
    1125 #undef DAC
    1126 #include "audio_template.h"
    1127 
    1128 int AUD_write (SWVoiceOut *sw, void *buf, int size)
     1403int AUD_get_buffer_size_out (PPDMGSTVOICEOUT sw)
     1404{
     1405    return sw->pHostVoiceOut->cSamples << sw->pHostVoiceOut->Props.cShift;
     1406}
     1407
     1408static int audio_get_avail (PPDMGSTVOICEIN sw)
     1409{
     1410    int live;
     1411
     1412    if (!sw)
     1413    {
     1414        LogFlow(("Error Voice Input Stream NUL \n"));
     1415        return 0;
     1416    }
     1417
     1418    live = sw->hw->cSamplesCaptured - sw->cHostSamplesAcquired;
     1419    if (live < 0 || live > sw->hw->cSamples)
     1420    {
     1421        LogFlow(("DrvAudio: Error, live=%d sw->hw->samples=%d\n", live, sw->hw->cSamples));
     1422        return 0;
     1423    }
     1424    return (((int64_t) live << 32) / sw->State.ratio) << sw->Props.cShift;
     1425}
     1426
     1427static int audio_get_free(PPDMGSTVOICEOUT sw)
     1428{
     1429    int live, dead;
     1430
     1431    if (!sw)
     1432    {
     1433        LogFlow(("DrvAudio: Error, guest voice output stream null \n"));
     1434        return 0;
     1435    }
     1436
     1437    live = sw->cSamplesMixed;
     1438
     1439    if (live < 0 || live > sw->pHostVoiceOut->cSamples)
     1440    {
     1441        LogFlow(("DrvAudio: Error, live=%d sw->hw->samples=%d\n", live, sw->pHostVoiceOut->cSamples));
     1442        return 0;
     1443    }
     1444    dead = sw->pHostVoiceOut->cSamples - live;
     1445    return (((int64_t) dead << 32) / sw->State.ratio) << sw->Props.cShift;
     1446}
     1447
     1448static void audio_capture_mix_and_clear (PDRVAUDIO pThis, PPDMHOSTVOICEOUT hw, int rpos, int samples)
     1449{
     1450    int n;
     1451    LogFlow(("audio_capture_mix_and_clear \n"));
     1452    if (hw->fEnabled)
     1453    {
     1454        SWVoiceCap *sc;
     1455        SWVoiceCap *pIter;
     1456
     1457        RTListForEach(&hw->HeadCapturedVoice, pIter, SWVoiceCap, ListCapturedVoice)
     1458        {
     1459            sc = pIter;
     1460            PPDMGSTVOICEOUT sw = &sc->sw;
     1461            int rpos2 = rpos;
     1462
     1463            n = samples;
     1464            while (n)
     1465            {
     1466                int till_end_of_hw = hw->cSamples - rpos2;
     1467                int to_write = audio_MIN (till_end_of_hw, n);
     1468                int bytes = to_write << hw->Props.cShift;
     1469                int written;
     1470
     1471                sw->buf = hw->pHostSterioSampleBuf + rpos2;
     1472                written = audio_pcm_sw_write (pThis, sw, NULL, bytes);
     1473                if (written - bytes) {
     1474                    LogFlow(("Could not mix %d bytes into a capture "
     1475                           "buffer, mixed %d\n",
     1476                           bytes, written));
     1477                    break;
     1478                }
     1479                n -= to_write;
     1480                rpos2 = (rpos2 + to_write) % hw->cSamples;
     1481            }
     1482        }
     1483    }
     1484
     1485    n = audio_MIN (samples, hw->cSamples - rpos);
     1486    mixeng_sniff_and_clear (hw, hw->pHostSterioSampleBuf + rpos, n);
     1487    mixeng_sniff_and_clear (hw, hw->pHostSterioSampleBuf, samples - n);
     1488}
     1489
     1490static void drvAudioPlayOut(PDRVAUDIO pThis)
     1491{
     1492    PPDMHOSTVOICEOUT hw = NULL;
     1493    PPDMGSTVOICEOUT sw;
     1494    PPDMGSTVOICEOUT pIter;
     1495    PPDMGSTVOICEOUT pIter1;
     1496
     1497    while ((hw = drvAudioHlpPcmHwFindAnyEnabledOut(pThis, hw)))
     1498    {
     1499        int played;
     1500        int live, myfree, nb_live, cleanup_required, prev_rpos;
     1501
     1502        live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
     1503        if (!nb_live)
     1504        {
     1505            LogFlow(("DrvAudio: Live samples 0\n"));
     1506            live = 0;
     1507        }
     1508
     1509        if (live < 0 || live > hw->cSamples)
     1510        {
     1511            LogFlow(("DrvAudio: live=%d hw->samples=%d\n", live, hw->cSamples));
     1512            continue;
     1513        }
     1514
     1515        if (hw->pending_disable && !nb_live)
     1516        {
     1517            SWVoiceCap *sc;
     1518            SWVoiceCap *pIter;
     1519            hw->fEnabled = 0;
     1520            hw->pending_disable = 0;
     1521            pThis->pHostDrvAudio->pfnDisableEnableOut(pThis->pHostDrvAudio, hw, VOICE_DISABLE);
     1522            RTListForEach(&hw->HeadCapturedVoice, pIter, SWVoiceCap , ListCapturedVoice)
     1523            {
     1524                sc = pIter;
     1525                sc->sw.State.fActive = 0;
     1526                drvAudioRecalcAndNotifyCapture(sc->cap);
     1527            }
     1528            continue;
     1529        }
     1530
     1531        if (!live)
     1532        {
     1533            RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut)
     1534            {
     1535                sw = pIter;
     1536                if (sw->State.fActive)
     1537                {
     1538                    myfree = audio_get_free (sw);
     1539                    if (myfree > 0)
     1540                        sw->callback.fn (sw->callback.opaque, myfree);
     1541                }
     1542            }
     1543            continue;
     1544        }
     1545
     1546        prev_rpos = hw->offRead;
     1547        played = pThis->pHostDrvAudio->pfnPlayOut(pThis->pHostDrvAudio, hw);
     1548        if (hw->offRead >= hw->cSamples)
     1549        {
     1550            LogFlow(("DrvAudio: hw->rpos=%d hw->samples=%d played=%d\n",
     1551                   hw->offRead, hw->cSamples, played));
     1552            hw->offRead = 0;
     1553        }
     1554        /* I think this code relates to the point to accomodate no of audio samples
     1555         * that have got accumulated during the above call of pfnplayout. So , it basically
     1556         * tries to mix the old samples that have already been played, new samples that have
     1557         * been gathered in due time of playing. Mix them up and send it to audiosniffer for
     1558         * to be sent to VRDP server to be played on the client.
     1559         */
     1560        if (played) {
     1561            audio_capture_mix_and_clear (pThis, hw, prev_rpos, played);
     1562        }
     1563
     1564        cleanup_required = 0;
     1565        RTListForEach(&hw->HeadGstVoiceOut, pIter1, PDMGSTVOICEOUT, ListGstVoiceOut)
     1566        {
     1567            sw = pIter1;
     1568            if (!sw->State.fActive && sw->State.fEmpty)
     1569                continue;
     1570
     1571            if (played > sw->cSamplesMixed)
     1572            {
     1573                LogFlow(("DrvAudio: played=%d sw->total_hw_samples_mixed=%d\n",
     1574                       played, sw->cSamplesMixed));
     1575                played = sw->cSamplesMixed;
     1576            }
     1577
     1578            sw->cSamplesMixed -= played;
     1579
     1580            if (!sw->cSamplesMixed)
     1581            {
     1582                sw->State.fEmpty = 1;
     1583                cleanup_required |= !sw->State.fActive && !sw->callback.fn;
     1584            }
     1585
     1586            if (sw->State.fActive)
     1587            {
     1588                myfree = audio_get_free (sw);
     1589                if (myfree > 0)
     1590                    sw->callback.fn (sw->callback.opaque, myfree);
     1591            }
     1592        }
     1593
     1594        if (cleanup_required)
     1595        {
     1596            PPDMGSTVOICEOUT sw1;
     1597            RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut)
     1598            {
     1599                sw = pIter;
     1600                if (!sw->State.fActive && !sw->callback.fn)
     1601                    drvAudioHlpCloseOut(pThis, &pThis->qemuSoundCard, sw);
     1602            }
     1603        }
     1604    }
     1605}
     1606
     1607static void drvAudioPlayIn(PDRVAUDIO pThis)
     1608{
     1609    PPDMHOSTVOICEIN hw = NULL;
     1610
     1611    while ((hw = drvAudioHlpPcmHwFindAnyEnabledIn(pThis, hw)))
     1612    {
     1613        PPDMGSTVOICEIN pIter;
     1614        int captured, min;
     1615        captured = pThis->pHostDrvAudio->pfnPlayIn(pThis->pHostDrvAudio, hw);
     1616
     1617        min = audio_pcm_hw_find_min_in (hw);
     1618        hw->cSamplesCaptured += captured - min;
     1619        hw->ts_helper += captured;
     1620
     1621        RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn)
     1622        {
     1623            pIter->cHostSamplesAcquired -= min;
     1624
     1625            if (pIter->State.fActive)
     1626            {
     1627                int avail;
     1628                avail = audio_get_avail (pIter);
     1629                if (avail > 0)
     1630                {
     1631                    pIter->callback.fn(pIter->callback.opaque, avail);
     1632                }
     1633            }
     1634        }
     1635    }
     1636}
     1637
     1638static void drvAudioCapture(PDRVAUDIO pThis)
     1639{
     1640    CaptureVoiceOut *cap;
     1641    CaptureVoiceOut *pIter;
     1642
     1643    RTListForEach(&pThis->HeadCapturedVoice, pIter, CaptureVoiceOut, ListCapturedVoice)
     1644    {
     1645        cap = pIter;
     1646        int live, rpos, captured;
     1647        PPDMHOSTVOICEOUT hw = &cap->hw;
     1648        PPDMGSTVOICEOUT sw;
     1649        PPDMGSTVOICEOUT pIter;
     1650
     1651        captured = live = audio_pcm_hw_get_live_out (hw);
     1652        rpos = hw->offRead;
     1653        while (live)
     1654        {
     1655            int left = hw->cSamples - rpos;
     1656            int to_capture = audio_MIN (live, left);
     1657            st_sample_t *src;
     1658            struct capture_callback *cb;
     1659
     1660            src = hw->pHostSterioSampleBuf + rpos;
     1661            clipAudio (cap->buf, src, to_capture);
     1662            mixeng_sniff_and_clear (hw, src, to_capture);
     1663
     1664            rpos = (rpos + to_capture) % hw->cSamples;
     1665            live -= to_capture;
     1666        }
     1667        hw->offRead = rpos;
     1668
     1669        RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut)
     1670        {
     1671            sw = pIter;
     1672            LogFlow(("6\n"));
     1673            if (!sw->State.fActive && sw->State.fEmpty) {
     1674                continue;
     1675            }
     1676
     1677            if (captured > sw->cSamplesMixed)
     1678            {
     1679                LogFlow(("DrvAudio: captured=%d sw->total_hw_samples_mixed=%d\n",
     1680                       captured, sw->cSamplesMixed));
     1681                captured = sw->cSamplesMixed;
     1682            }
     1683
     1684            sw->cSamplesMixed -= captured;
     1685            sw->State.fEmpty = sw->cSamplesMixed == 0;
     1686        }
     1687    }
     1688}
     1689static void drvAudioTimer(PDRVAUDIO pThis)
     1690{
     1691        drvAudioPlayOut(pThis);
     1692        drvAudioPlayIn(pThis);
     1693        drvAudioCapture(pThis);
     1694        TMTimerSet (pThis->pTimer, TMTimerGet (pThis->pTimer) + pThis->ticks);
     1695}
     1696
     1697static int audio_driver_init (PCFGMNODE pCfgHandle, PDRVAUDIO pThis, struct audio_driver *drv)
     1698{
     1699    int max_voices;
     1700    int voice_size;
     1701    if (drv->options)
     1702    {
     1703        drvAudioProcessOptions(pCfgHandle, drv->name, drv->options);
     1704    }
     1705    if (!pThis->pHostDrvAudio->pfnInit(pThis->pHostDrvAudio))
     1706    {
     1707        LogFlow(("DrvAudio: Could not init audio driver %p\n", pThis));
     1708        return VERR_GENERAL_FAILURE;
     1709    }
     1710
     1711    max_voices = pThis->AudioConf.MaxHostVoicesOut;
     1712    voice_size = pThis->AudioConf.szHostVoiceOut;
     1713    pThis->cHostOutVoices = 1;
     1714    if (pThis->cHostOutVoices > max_voices)
     1715    {
     1716        if (!max_voices)
     1717            LogFlow(("Driver `%s' does not support \n", drv->name));
     1718        else
     1719            LogFlow(("Driver `%s' does not support %d   voices, max %d\n",
     1720                   drv->name,
     1721                   pThis->cHostOutVoices,
     1722                   max_voices));
     1723        pThis->cHostOutVoices = 1;//max_voices;
     1724    }
     1725
     1726    if (!voice_size && max_voices)
     1727    {
     1728        LogFlow(("drv=`%s' voice_size=0 max_voices=%d\n",
     1729               drv->name, max_voices));
     1730        pThis->cHostOutVoices = 0;
     1731    }
     1732
     1733    if (voice_size && !max_voices)
     1734    {
     1735        LogFlow(("drv=`%s' voice_size=%d max_voices=0\n",
     1736               drv->name, voice_size));
     1737    }
     1738
     1739
     1740    max_voices = pThis->AudioConf.MaxHostVoicesIn;
     1741    voice_size = pThis->AudioConf.szHostVoiceIn;
     1742
     1743    LogFlow(("DrvAudio: voice_size =%d max_voices=%d cHostInVoices=%d\n", voice_size, max_voices, pThis->cHostInVoices));
     1744    //pThis->cHostInVoices = 1; //@todo handle this
     1745    if (pThis->cHostInVoices > max_voices)
     1746    {
     1747        if (!max_voices)
     1748            LogFlow(("Driver `%s' does not support \n", drv->name));
     1749        else
     1750            LogFlow(("Driver `%s' does not support %d   voices, max %d\n",
     1751                   drv->name,
     1752                   pThis->cHostOutVoices,
     1753                   max_voices));
     1754        pThis->cHostInVoices = max_voices;
     1755    }
     1756
     1757    if (!voice_size && max_voices)
     1758    {
     1759        LogFlow(("drv=`%s' voice_size=0 max_voices=%d\n",
     1760               drv->name, max_voices));
     1761        //@todo in original code its 0, but I have made it 1 to avoid crash
     1762        pThis->cHostInVoices = 0;
     1763    }
     1764
     1765    if (voice_size && !max_voices)
     1766    {
     1767        LogFlow(("drv=`%s' voice_size=%d max_voices=0\n",
     1768               drv->name, voice_size));
     1769    }
     1770    return VINF_SUCCESS;
     1771}
     1772
     1773static void audio_vm_change_state_handler (PPDMDRVINS pDrvIns,/* void *opaque,*/ int running)
     1774{
     1775    PPDMHOSTVOICEOUT hwo = NULL;
     1776    PPDMHOSTVOICEIN hwi = NULL;
     1777    PDRVAUDIO  pThis   = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
     1778    int op = running ? VOICE_ENABLE : VOICE_DISABLE;
     1779
     1780    while ((hwo = drvAudioHlpPcmHwFindAnyEnabledOut(pThis, hwo))) {
     1781        pThis->pHostDrvAudio->pfnDisableEnableOut(pThis->pHostDrvAudio, hwo, op);
     1782    }
     1783
     1784    while ((hwi = drvAudioHlpPcmHwFindAnyEnabledIn(pThis, hwi))) {
     1785        pThis->pHostDrvAudio->pfnDisableEnableIn(pThis->pHostDrvAudio, hwi, op);
     1786    }
     1787}
     1788
     1789static void drvAudioExit(PPDMDRVINS pDrvIns)
     1790{
     1791    PPDMHOSTVOICEOUT hwo = NULL;
     1792    PPDMHOSTVOICEIN hwi = NULL;
     1793    PDRVAUDIO  pThis   = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
     1794    /* VBox change: audio_pcm_hw_find_any_enabled_out => audio_pcm_hw_find_any_out */
     1795    while ((hwo = drvAudioHlpPcmHwFindAnyOut(pThis, hwo)))
     1796    {
     1797        SWVoiceCap *sc;
     1798        SWVoiceCap *pIter;
     1799
     1800        pThis->pHostDrvAudio->pfnDisableEnableOut(pThis->pHostDrvAudio, hwo, VOICE_DISABLE);
     1801        pThis->pHostDrvAudio->pfnFiniOut(pThis->pHostDrvAudio, hwo);
     1802
     1803        RTListForEach(&hwo->HeadCapturedVoice, pIter, SWVoiceCap, ListCapturedVoice)
     1804        {
     1805            sc = pIter;
     1806            CaptureVoiceOut *cap = sc->cap;
     1807            struct capture_callback *cb;
     1808        }
     1809    }
     1810
     1811    /* VBox change: audio_pcm_hw_find_any_enabled_in => audio_pcm_hw_find_any_in */
     1812    while ((hwi = drvAudioHlpPcmHwFindAnyIn(pThis, hwi)))
     1813    {
     1814        pThis->pHostDrvAudio->pfnDisableEnableIn(pThis->pHostDrvAudio, hwi, VOICE_DISABLE);
     1815        pThis->pHostDrvAudio->pfnFiniIn(pThis->pHostDrvAudio, hwi);
     1816    }
     1817}
     1818
     1819static DECLCALLBACK(void) audio_timer_helper (PPDMDRVINS pDrvIns, PTMTIMER pTimer, void *pvUser)
     1820{
     1821    PDRVAUDIO  pThis   = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
     1822    drvAudioTimer(pThis);
     1823}
     1824
     1825static struct audio_option audio_options[] =
     1826{
     1827    /* DAC */
     1828    {"DACFixedSettings", AUD_OPT_BOOL, &conf.fixed_out.enabled,
     1829     "Use fixed settings for host DAC", NULL, 0},
     1830
     1831    {"DACFixedFreq", AUD_OPT_INT, &conf.fixed_out.settings.freq,
     1832     "Frequency for fixed host DAC", NULL, 0},
     1833
     1834    {"DACFixedFmt", AUD_OPT_FMT, &conf.fixed_out.settings.fmt,
     1835     "Format for fixed host DAC", NULL, 0},
     1836
     1837    {"DACFixedChannels", AUD_OPT_INT, &conf.fixed_out.settings.nchannels,
     1838     "Number of channels for fixed DAC (1 - mono, 2 - stereo)", NULL, 0},
     1839
     1840    {"DACVoices", AUD_OPT_INT, &conf.fixed_out.nb_voices,
     1841     "Number of voices for DAC", NULL, 0},
     1842
     1843    /* ADC */
     1844    {"ADCFixedSettings", AUD_OPT_BOOL, &conf.fixed_in.enabled,
     1845     "Use fixed settings for host ADC", NULL, 0},
     1846
     1847    {"ADCFixedFreq", AUD_OPT_INT, &conf.fixed_in.settings.freq,
     1848     "Frequency for fixed host ADC", NULL, 0},
     1849
     1850    {"ADCFixedFmt", AUD_OPT_FMT, &conf.fixed_in.settings.fmt,
     1851     "Format for fixed host ADC", NULL, 0},
     1852
     1853    {"ADCFixedChannels", AUD_OPT_INT, &conf.fixed_in.settings.nchannels,
     1854     "Number of channels for fixed ADC (1 - mono, 2 - stereo)", NULL, 0},
     1855
     1856    {"ADCVoices", AUD_OPT_INT, &conf.fixed_in.nb_voices,
     1857     "Number of voices for ADC", NULL, 0},
     1858
     1859    /* Misc */
     1860    {"TimerFreq", AUD_OPT_INT, &conf.period.hz,
     1861     "Timer frequency in Hz (0 - use lowest possible)", NULL, 0},
     1862
     1863    {"PLIVE", AUD_OPT_BOOL, &conf.plive,
     1864     "(undocumented)", NULL, 0},
     1865
     1866    {NULL, 0, NULL, NULL, NULL, 0}
     1867};
     1868
     1869static DECLCALLBACK (void) drvAudioRegisterCard(PPDMIAUDIOCONNECTOR pInterface, const char *name)
     1870{
     1871    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     1872    LogFlow(("DrvAudio: drvAudioRegisterCard \n"));
     1873    pThis->qemuSoundCard.name = RTStrDup(name);
     1874}
     1875
     1876static DECLCALLBACK(int) drvAudioInit(PCFGMNODE pCfgHandle, PPDMDRVINS pDrvIns, const char *drvname, PDRVAUDIO  pDrvAudio)
     1877{
     1878    size_t i;
     1879    int done = 0;
     1880    int rc;
     1881    PDRVAUDIO  pThis  = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
     1882    LogFlow(("DrvAudio: drvAudioInit pDrvAudio=%p and pDrvIns=%p\n", pDrvAudio, pDrvIns));
     1883
     1884    RTListInit(&pDrvAudio->HeadHostVoiceOut);
     1885    RTListInit(&pDrvAudio->HeadHostVoiceIn);
     1886    RTListInit(&pDrvAudio->HeadHostVoiceIn);
     1887    RTListInit(&pDrvAudio->HeadCapturedVoice);
     1888
     1889    /* get the configuration data from the backend */
     1890    pDrvAudio->pHostDrvAudio->pfnGetConf(pDrvAudio->pHostDrvAudio, &pDrvAudio->AudioConf);
     1891
     1892    rc = PDMDrvHlpTMTimerCreate (pDrvIns, TMCLOCK_VIRTUAL, audio_timer_helper,
     1893                                 pThis, 0, "Audio timer", &pDrvAudio->pTimer);
     1894    if (RT_FAILURE (rc))
     1895    {
     1896        LogRel(("DrvAudio: Failed to create timer \n"));
     1897        return rc;
     1898   }
     1899
     1900    drvAudioProcessOptions(pCfgHandle, "AUDIO", audio_options);
     1901
     1902    pDrvAudio->cHostOutVoices = conf.fixed_out.nb_voices;
     1903    pDrvAudio->cHostInVoices = conf.fixed_in.nb_voices;
     1904
     1905    pDrvAudio->ticks = 200; /* initialization of ticks */
     1906
     1907    /* initialization of audio buffer. Create ring buffer of around 200 KB each . */
     1908    IORingBufferCreate(&pDrvAudio->pAudioWriteBuf, 512000); /* 500 KB */
     1909
     1910    /* allocating space for about 500 msec of audio data 48KHz, 128 bit sample
     1911     * (guest format - PDMHOSTSTEREOSAMPLE) and dual channel
     1912     */
     1913    IORingBufferCreate(&pDrvAudio->pAudioReadBuf, 768000); /* 750 KB */
     1914
     1915
     1916    if (pDrvAudio->cHostOutVoices <= 0)
     1917    {
     1918        LogFlow(("Bogus number of playback voices %d, setting to 1\n", pDrvAudio->cHostOutVoices));
     1919        pDrvAudio->cHostOutVoices = 1;
     1920    }
     1921
     1922    if (pDrvAudio->cHostInVoices <= 0)
     1923    {
     1924        LogFlow(("Bogus number of capture voices %d, setting to 0\n", pDrvAudio->cHostInVoices));
     1925        //@todo in original code its set to 0 currently being set to 1 to ensure atleas 1 voice IN
     1926        pDrvAudio->cHostInVoices = 1;
     1927    }
     1928    LogFlow(("Audio: Trying driver '%s'.\n", drvname));
     1929
     1930    if (drvname)
     1931    {
     1932        int found = 0;
     1933        for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++)
     1934        {
     1935            /* @todo: audioVRDE name wont be visible here. So hardcoding */
     1936            if (!strcmp (drvname, drvtab[i]->name) || !strcmp(drvname, "AudioVRDE"))
     1937            {
     1938                if (!strcmp(drvname, "AudioVRDE"))
     1939                {
     1940                    struct audio_driver vrde_audio_driver =
     1941                    {
     1942                        INIT_FIELD (name           = ) "AudioVRDE",
     1943                        INIT_FIELD (descr          = ) "AudioVRDE http://www.pulseaudio.org",
     1944                        INIT_FIELD (options        = ) NULL,
     1945                    };
     1946                    struct audio_driver *drvtabAudioVRDE = &vrde_audio_driver;
     1947                        done = !audio_driver_init (pCfgHandle, pDrvAudio, drvtabAudioVRDE);
     1948                }
     1949                else
     1950                {
     1951                    done = !audio_driver_init (pCfgHandle, pDrvAudio, drvtab[i]);
     1952                }
     1953                found = 1;
     1954                break;
     1955            }
     1956        }
     1957
     1958        if (!found)
     1959        {
     1960            LogFlow(("Audio: Unknown audio driver `%s'\n", drvname));
     1961        }
     1962    }
     1963
     1964    if (!done)
     1965    {
     1966        for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
     1967            if (drvtab[i]->can_be_default) {
     1968                LogRel(("Audio: Initialization of driver '%s' failed, trying '%s'.\n",drvname, drvtab[i]->name));
     1969                drvname = drvtab[i]->name;
     1970                done = !audio_driver_init (pCfgHandle, pDrvAudio, drvtab[i]);
     1971            }
     1972        }
     1973    }
     1974
     1975    if (!done) {
     1976        done = !audio_driver_init (pCfgHandle, pThis, &no_audio_driver);
     1977        if (!done) {
     1978            LogFlow(("Could not initialize audio subsystem\n"));
     1979        }
     1980        else {
     1981            LogRel(("Audio: Initialization of driver '%s' failed, using NULL driver.\n", drvname));
     1982            LogFlow(("warning: Using timer based audio emulation\n"));
     1983        }
     1984    }
     1985    if (done)
     1986    {
     1987        if (conf.period.hz <= 0)
     1988        {
     1989            if (conf.period.hz < 0)
     1990            {
     1991                LogFlow(("warning: Timer period is negative - %d "
     1992                       "treating as zero\n",
     1993                       conf.period.hz));
     1994            }
     1995            pDrvAudio->ticks = 1;
     1996        }
     1997        else
     1998        {
     1999            pDrvAudio->ticks =  PDMDrvHlpTMGetVirtualFreq(pDrvIns) / conf.period.hz;
     2000        }
     2001    }
     2002    else {
     2003        /* XXX */
     2004        rc = TMR3TimerDestroy (pDrvAudio->pTimer);
     2005        return rc;
     2006    }
     2007    TMTimerSet (pDrvAudio->pTimer, TMTimerGet (pDrvAudio->pTimer) + pDrvAudio->ticks);
     2008    return VINF_SUCCESS;
     2009}
     2010static DECLCALLBACK(int) drvAudioInitNull(PPDMIAUDIOCONNECTOR pInterface)
     2011{
     2012    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     2013    return audio_driver_init(NULL, pThis, &no_audio_driver);
     2014}
     2015
     2016static DECLCALLBACK(int) drvAudioWrite(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT sw, void *buf, int size)
    11292017{
    11302018    int bytes;
    1131 
     2019    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     2020    if (!sw || size < 0)
     2021    {
     2022        LogFlow(("DrvAudio: GstVoiceOut is NULL \n"));
     2023        /* XXX: Consider options */
     2024        return size;
     2025    }
     2026
     2027    if (!sw->pHostVoiceOut->fEnabled) {
     2028        return 0;
     2029    }
     2030    bytes = audio_pcm_sw_write(pThis, sw, buf, size);
     2031    return bytes;
     2032}
     2033
     2034static DECLCALLBACK(int) drvAudioRead(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN sw, void *buf, int size)
     2035{
     2036    int bytes;
     2037    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
    11322038    if (!sw) {
    11332039        /* XXX: Consider options */
     
    11362042
    11372043    if (!sw->hw->enabled) {
    1138         dolog ("Writing to disabled voice %s\n", SW_NAME (sw));
     2044        LogFlow(("DrvAudio: Reading from disabled voice \n"));
    11392045        return 0;
    11402046    }
    1141 
    1142     bytes = sw->hw->pcm_ops->write (sw, buf, size);
     2047    bytes = audio_pcm_sw_read(pThis, sw, (PPDMHOSTSTEREOSAMPLE)buf, size);
    11432048    return bytes;
    11442049}
    11452050
    1146 int AUD_read (SWVoiceIn *sw, void *buf, int size)
    1147 {
    1148     int bytes;
    1149 
    1150     if (!sw) {
    1151         /* XXX: Consider options */
    1152         return size;
    1153     }
    1154 
    1155     if (!sw->hw->enabled) {
    1156         dolog ("Reading from disabled voice %s\n", SW_NAME (sw));
    1157         return 0;
    1158     }
    1159 
    1160     bytes = sw->hw->pcm_ops->read (sw, buf, size);
    1161     return bytes;
    1162 }
    1163 
    1164 int AUD_get_buffer_size_out (SWVoiceOut *sw)
    1165 {
    1166     return sw->hw->samples << sw->hw->info.shift;
    1167 }
    1168 
    1169 void AUD_set_active_out (SWVoiceOut *sw, int on)
    1170 {
    1171     HWVoiceOut *hw;
    1172 
    1173     if (!sw) {
     2051static DECLCALLBACK(void) drvAudioIsSetOutVolume (PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT sw, int mute, uint8_t lvol, uint8_t rvol)
     2052{
     2053    if (sw)
     2054    {
     2055        sw->State.uVolumeMute = mute;
     2056        sw->State.uVolumeLeft    = (uint32_t)lvol * 0x808080; /* maximum is INT_MAX = 0x7fffffff */
     2057        sw->State.uVolumeRight    = (uint32_t)rvol * 0x808080; /* maximum is INT_MAX = 0x7fffffff */
     2058    }
     2059}
     2060
     2061
     2062static DECLCALLBACK(void) drvAudioSetVolume (PPDMIAUDIOCONNECTOR pInterface, int *mute, uint8_t *lvol, uint8_t *rvol)
     2063{
     2064    volume_t vol;
     2065    const char *name;
     2066
     2067    uint32_t u32VolumeLeft  = (uint32_t)*lvol;
     2068    uint32_t u32VolumeRight = (uint32_t)*rvol;
     2069    /* 0x00..0xff => 0x01..0x100 */
     2070    if (u32VolumeLeft)
     2071        u32VolumeLeft++;
     2072    if (u32VolumeRight)
     2073        u32VolumeRight++;
     2074    vol.mute  = *mute;
     2075    vol.l     = u32VolumeLeft  * 0x800000; /* maximum is 0x80000000 */
     2076    vol.r     = u32VolumeRight * 0x800000; /* maximum is 0x80000000 */
     2077    sum_out_volume.mute = 0;
     2078    sum_out_volume.l    = ASMMultU64ByU32DivByU32(INT_MAX, INT_MAX, 0x80000000U);
     2079    sum_out_volume.r    = ASMMultU64ByU32DivByU32(INT_MAX, INT_MAX, 0x80000000U);
     2080}
     2081
     2082static DECLCALLBACK(void) drvAudioEnableOut (PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT sw, int on)
     2083{
     2084    PPDMHOSTVOICEOUT hw;
     2085    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     2086
     2087    if (!sw)
    11742088        return;
    1175     }
    1176 
    1177     hw = sw->hw;
    1178     if (sw->active != on) {
    1179         SWVoiceOut *temp_sw;
     2089
     2090    hw = sw->pHostVoiceOut;
     2091    if (sw->State.fActive != on)
     2092    {
     2093        PPDMGSTVOICEOUT pIter;
    11802094        SWVoiceCap *sc;
    1181 
    1182         if (on) {
     2095        SWVoiceCap *pIterCap;
     2096
     2097        if (on)
     2098        {
    11832099            hw->pending_disable = 0;
    1184             if (!hw->enabled) {
    1185                 hw->enabled = 1;
    1186                 hw->pcm_ops->ctl_out (hw, VOICE_ENABLE);
     2100            if (!hw->fEnabled)
     2101            {
     2102                hw->fEnabled = 1;
     2103                pThis->pHostDrvAudio->pfnDisableEnableOut(pThis->pHostDrvAudio, hw, VOICE_ENABLE);
    11872104            }
    11882105        }
    1189         else {
    1190             if (hw->enabled) {
     2106        else
     2107        {
     2108            if (hw->fEnabled)
     2109            {
    11912110                int nb_active = 0;
    11922111
    1193                 for (temp_sw = hw->sw_head.lh_first; temp_sw;
    1194                      temp_sw = temp_sw->entries.le_next) {
    1195                     nb_active += temp_sw->active != 0;
     2112                RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut)
     2113                {
     2114                    nb_active += pIter->State.fActive != 0;
    11962115                }
    11972116
     
    12002119        }
    12012120
    1202         for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
    1203             sc->sw.active = hw->enabled;
    1204             if (hw->enabled) {
     2121        RTListForEach(&hw->HeadCapturedVoice, pIterCap, SWVoiceCap, ListCapturedVoice)
     2122        {
     2123            sc = pIterCap;
     2124            sc->sw.State.fActive = hw->fEnabled;
     2125            if (hw->fEnabled) {
    12052126                audio_capture_maybe_changed (sc->cap, 1);
    12062127            }
    12072128        }
    1208         sw->active = on;
    1209     }
    1210 }
    1211 
    1212 void AUD_set_active_in (SWVoiceIn *sw, int on)
    1213 {
    1214     HWVoiceIn *hw;
    1215 
     2129        sw->State.fActive = on;
     2130    }
     2131}
     2132
     2133static DECLCALLBACK(void) drvAudioEnableIn(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN sw , int on)
     2134{
     2135    PPDMHOSTVOICEIN hw;
     2136    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
    12162137    if (!sw) {
     2138        LogFlow(("DrvAudio: NO GuestVoiceIn. Returning 0\n"));
    12172139        return;
    12182140    }
    12192141
    12202142    hw = sw->hw;
    1221     if (sw->active != on) {
    1222         SWVoiceIn *temp_sw;
    1223 
    1224         if (on) {
    1225             if (!hw->enabled) {
     2143    if (sw->State.fActive != on)
     2144    {
     2145        PPDMGSTVOICEIN pIter;
     2146
     2147        if (on)
     2148        {
     2149            if (!hw->enabled)
     2150            {
    12262151                hw->enabled = 1;
    1227                 hw->pcm_ops->ctl_in (hw, VOICE_ENABLE);
     2152                pThis->pHostDrvAudio->pfnDisableEnableIn(pThis->pHostDrvAudio, hw, VOICE_ENABLE);
    12282153            }
    1229             sw->total_hw_samples_acquired = hw->total_samples_captured;
    1230         }
    1231         else {
    1232             if (hw->enabled) {
     2154            sw->cHostSamplesAcquired = hw->cSamplesCaptured;
     2155        }
     2156        else
     2157        {
     2158            if (hw->enabled)
     2159            {
    12332160                int nb_active = 0;
    12342161
    1235                 for (temp_sw = hw->sw_head.lh_first; temp_sw;
    1236                      temp_sw = temp_sw->entries.le_next) {
    1237                     nb_active += temp_sw->active != 0;
     2162                RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn)
     2163                {
     2164                    nb_active += pIter->State.fActive != 0;
    12382165                }
    12392166
    12402167                if (nb_active == 1) {
    12412168                    hw->enabled = 0;
    1242                     hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);
     2169                    pThis->pHostDrvAudio->pfnDisableEnableIn(pThis->pHostDrvAudio, hw, VOICE_DISABLE);
    12432170                }
    12442171            }
    12452172        }
    1246         sw->active = on;
    1247     }
    1248 }
    1249 
    1250 static int audio_get_avail (SWVoiceIn *sw)
    1251 {
    1252     int live;
    1253 
    1254     if (!sw) {
    1255         return 0;
    1256     }
    1257 
    1258     live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
    1259     if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
    1260         dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
    1261         return 0;
    1262     }
    1263 
    1264     ldebug (
    1265         "%s: get_avail live %d ret %lld\n",
    1266         SW_NAME (sw),
    1267         live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift
    1268         );
    1269 
    1270     return (((int64_t) live << 32) / sw->ratio) << sw->info.shift;
    1271 }
    1272 
    1273 static int audio_get_free (SWVoiceOut *sw)
    1274 {
    1275     int live, dead;
    1276 
    1277     if (!sw) {
    1278         return 0;
    1279     }
    1280 
    1281     live = sw->total_hw_samples_mixed;
    1282 
    1283     if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
    1284         dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
    1285         return 0;
    1286     }
    1287 
    1288     dead = sw->hw->samples - live;
    1289 
    1290 #ifdef DEBUG_OUT
    1291     dolog ("%s: get_free live %d dead %d ret %lld\n",
    1292            SW_NAME (sw),
    1293            live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift);
    1294 #endif
    1295 
    1296     return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
    1297 }
    1298 
    1299 static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
    1300 {
    1301     int n;
    1302 
    1303     if (hw->enabled) {
    1304         SWVoiceCap *sc;
    1305 
    1306         for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
    1307             SWVoiceOut *sw = &sc->sw;
    1308             int rpos2 = rpos;
    1309 
    1310             n = samples;
    1311             while (n) {
    1312                 int till_end_of_hw = hw->samples - rpos2;
    1313                 int to_write = audio_MIN (till_end_of_hw, n);
    1314                 int bytes = to_write << hw->info.shift;
    1315                 int written;
    1316 
    1317                 sw->buf = hw->mix_buf + rpos2;
    1318                 written = audio_pcm_sw_write (sw, NULL, bytes);
    1319                 if (written - bytes) {
    1320                     dolog ("Could not mix %d bytes into a capture "
    1321                            "buffer, mixed %d\n",
    1322                            bytes, written);
    1323                     break;
    1324                 }
    1325                 n -= to_write;
    1326                 rpos2 = (rpos2 + to_write) % hw->samples;
    1327             }
    1328         }
    1329     }
    1330 
    1331     n = audio_MIN (samples, hw->samples - rpos);
    1332     mixeng_sniff_and_clear (hw, hw->mix_buf + rpos, n);
    1333     mixeng_sniff_and_clear (hw, hw->mix_buf, samples - n);
    1334 }
    1335 
    1336 static void audio_run_out (AudioState *s)
    1337 {
    1338     HWVoiceOut *hw = NULL;
    1339     SWVoiceOut *sw;
    1340 
    1341     while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) {
    1342         int played;
    1343         int live, myfree, nb_live, cleanup_required, prev_rpos;
    1344 
    1345         live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
    1346         if (!nb_live) {
    1347             live = 0;
    1348         }
    1349 
    1350         if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
    1351             dolog ("live=%d hw->samples=%d\n", live, hw->samples);
    1352             continue;
    1353         }
    1354 
    1355         if (hw->pending_disable && !nb_live) {
    1356             SWVoiceCap *sc;
    1357 #ifdef DEBUG_OUT
    1358             dolog ("Disabling voice\n");
    1359 #endif
    1360             hw->enabled = 0;
    1361             hw->pending_disable = 0;
    1362             hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
    1363             for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
    1364                 sc->sw.active = 0;
    1365                 audio_recalc_and_notify_capture (sc->cap);
    1366             }
    1367             continue;
    1368         }
    1369 
    1370         if (!live) {
    1371             for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
    1372                 if (sw->active) {
    1373                     myfree = audio_get_free (sw);
    1374                     if (myfree > 0) {
    1375                         sw->callback.fn (sw->callback.opaque, myfree);
    1376                     }
    1377                 }
    1378             }
    1379             continue;
    1380         }
    1381 
    1382         prev_rpos = hw->rpos;
    1383         played = hw->pcm_ops->run_out (hw);
    1384         if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
    1385             dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
    1386                    hw->rpos, hw->samples, played);
    1387             hw->rpos = 0;
    1388         }
    1389 
    1390 #ifdef DEBUG_OUT
    1391         dolog ("played=%d\n", played);
    1392 #endif
    1393 
    1394         if (played) {
    1395             hw->ts_helper += played;
    1396             audio_capture_mix_and_clear (hw, prev_rpos, played);
    1397         }
    1398 
    1399         cleanup_required = 0;
    1400         for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
    1401             if (!sw->active && sw->empty) {
    1402                 continue;
    1403             }
    1404 
    1405             if (audio_bug (AUDIO_FUNC, played > sw->total_hw_samples_mixed)) {
    1406                 dolog ("played=%d sw->total_hw_samples_mixed=%d\n",
    1407                        played, sw->total_hw_samples_mixed);
    1408                 played = sw->total_hw_samples_mixed;
    1409             }
    1410 
    1411             sw->total_hw_samples_mixed -= played;
    1412 
    1413             if (!sw->total_hw_samples_mixed) {
    1414                 sw->empty = 1;
    1415                 cleanup_required |= !sw->active && !sw->callback.fn;
    1416             }
    1417 
    1418             if (sw->active) {
    1419                 myfree = audio_get_free (sw);
    1420                 if (myfree > 0) {
    1421                     sw->callback.fn (sw->callback.opaque, myfree);
    1422                 }
    1423             }
    1424         }
    1425 
    1426         if (cleanup_required) {
    1427             SWVoiceOut *sw1;
    1428 
    1429             sw = hw->sw_head.lh_first;
    1430             while (sw) {
    1431                 sw1 = sw->entries.le_next;
    1432                 if (!sw->active && !sw->callback.fn) {
    1433 #ifdef DEBUG_PLIVE
    1434                     dolog ("Finishing with old voice\n");
    1435 #endif
    1436                     audio_close_out (s, sw);
    1437                 }
    1438                 sw = sw1;
    1439             }
    1440         }
    1441     }
    1442 }
    1443 
    1444 static void audio_run_in (AudioState *s)
    1445 {
    1446     HWVoiceIn *hw = NULL;
    1447 
    1448     while ((hw = audio_pcm_hw_find_any_enabled_in (s, hw))) {
    1449         SWVoiceIn *sw;
    1450         int captured, min;
    1451 
    1452         captured = hw->pcm_ops->run_in (hw);
    1453 
    1454         min = audio_pcm_hw_find_min_in (hw);
    1455         hw->total_samples_captured += captured - min;
    1456         hw->ts_helper += captured;
    1457 
    1458         for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
    1459             sw->total_hw_samples_acquired -= min;
    1460 
    1461             if (sw->active) {
    1462                 int avail;
    1463 
    1464                 avail = audio_get_avail (sw);
    1465                 if (avail > 0) {
    1466                     sw->callback.fn (sw->callback.opaque, avail);
    1467                 }
    1468             }
    1469         }
    1470     }
    1471 }
    1472 
    1473 static void audio_run_capture (AudioState *s)
    1474 {
    1475     CaptureVoiceOut *cap;
    1476 
    1477     for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
    1478         int live, rpos, captured;
    1479         HWVoiceOut *hw = &cap->hw;
    1480         SWVoiceOut *sw;
    1481 
    1482         captured = live = audio_pcm_hw_get_live_out (hw);
    1483         rpos = hw->rpos;
    1484         while (live) {
    1485             int left = hw->samples - rpos;
    1486             int to_capture = audio_MIN (live, left);
    1487             st_sample_t *src;
    1488             struct capture_callback *cb;
    1489 
    1490             src = hw->mix_buf + rpos;
    1491             hw->clip (cap->buf, src, to_capture);
    1492             mixeng_sniff_and_clear (hw, src, to_capture);
    1493 
    1494             for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
    1495                 cb->ops.capture (cb->opaque, cap->buf,
    1496                                  to_capture << hw->info.shift);
    1497             }
    1498             rpos = (rpos + to_capture) % hw->samples;
    1499             live -= to_capture;
    1500         }
    1501         hw->rpos = rpos;
    1502 
    1503         for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
    1504             if (!sw->active && sw->empty) {
    1505                 continue;
    1506             }
    1507 
    1508             if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) {
    1509                 dolog ("captured=%d sw->total_hw_samples_mixed=%d\n",
    1510                        captured, sw->total_hw_samples_mixed);
    1511                 captured = sw->total_hw_samples_mixed;
    1512             }
    1513 
    1514             sw->total_hw_samples_mixed -= captured;
    1515             sw->empty = sw->total_hw_samples_mixed == 0;
    1516         }
    1517     }
    1518 }
    1519 
    1520 static void audio_timer (void *opaque)
    1521 {
    1522     AudioState *s = opaque;
    1523 
    1524     audio_run_out (s);
    1525     audio_run_in (s);
    1526     audio_run_capture (s);
    1527 
    1528     TMTimerSet (s->ts, TMTimerGet (s->ts) + conf.period.ticks);
    1529 }
    1530 
    1531 static struct audio_option audio_options[] = {
    1532     /* DAC */
    1533     {"DACFixedSettings", AUD_OPT_BOOL, &conf.fixed_out.enabled,
    1534      "Use fixed settings for host DAC", NULL, 0},
    1535 
    1536     {"DACFixedFreq", AUD_OPT_INT, &conf.fixed_out.settings.freq,
    1537      "Frequency for fixed host DAC", NULL, 0},
    1538 
    1539     {"DACFixedFmt", AUD_OPT_FMT, &conf.fixed_out.settings.fmt,
    1540      "Format for fixed host DAC", NULL, 0},
    1541 
    1542     {"DACFixedChannels", AUD_OPT_INT, &conf.fixed_out.settings.nchannels,
    1543      "Number of channels for fixed DAC (1 - mono, 2 - stereo)", NULL, 0},
    1544 
    1545     {"DACVoices", AUD_OPT_INT, &conf.fixed_out.nb_voices,
    1546      "Number of voices for DAC", NULL, 0},
    1547 
    1548     /* ADC */
    1549     {"ADCFixedSettings", AUD_OPT_BOOL, &conf.fixed_in.enabled,
    1550      "Use fixed settings for host ADC", NULL, 0},
    1551 
    1552     {"ADCFixedFreq", AUD_OPT_INT, &conf.fixed_in.settings.freq,
    1553      "Frequency for fixed host ADC", NULL, 0},
    1554 
    1555     {"ADCFixedFmt", AUD_OPT_FMT, &conf.fixed_in.settings.fmt,
    1556      "Format for fixed host ADC", NULL, 0},
    1557 
    1558     {"ADCFixedChannels", AUD_OPT_INT, &conf.fixed_in.settings.nchannels,
    1559      "Number of channels for fixed ADC (1 - mono, 2 - stereo)", NULL, 0},
    1560 
    1561     {"ADCVoices", AUD_OPT_INT, &conf.fixed_in.nb_voices,
    1562      "Number of voices for ADC", NULL, 0},
    1563 
    1564     /* Misc */
    1565     {"TimerFreq", AUD_OPT_INT, &conf.period.hz,
    1566      "Timer frequency in Hz (0 - use lowest possible)", NULL, 0},
    1567 
    1568     {"PLIVE", AUD_OPT_BOOL, &conf.plive,
    1569      "(undocumented)", NULL, 0},
    1570 
    1571     {NULL, 0, NULL, NULL, NULL, 0}
    1572 };
    1573 
    1574 static int audio_driver_init (PCFGMNODE pCfgHandle, AudioState *s, struct audio_driver *drv)
    1575 {
    1576     if (drv->options) {
    1577         audio_process_options (pCfgHandle, drv->name, drv->options);
    1578     }
    1579     s->drv_opaque = drv->init ();
    1580 
    1581     if (s->drv_opaque) {
    1582         /* Filter must be installed before initializing voices. */
    1583         drv = filteraudio_install(drv, s->drv_opaque);
    1584         audio_init_nb_voices_out (s, drv);
    1585         audio_init_nb_voices_in (s, drv);
    1586         s->drv = drv;
    1587         return 0;
    1588     }
    1589     else {
    1590         dolog ("Could not init `%s' audio driver\n", drv->name);
    1591         return -1;
    1592     }
    1593 }
    1594 
    1595 static void audio_vm_change_state_handler (void *opaque, int running)
    1596 {
    1597     AudioState *s = opaque;
    1598     HWVoiceOut *hwo = NULL;
    1599     HWVoiceIn *hwi = NULL;
    1600     int op = running ? VOICE_ENABLE : VOICE_DISABLE;
    1601 
    1602     while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
    1603         hwo->pcm_ops->ctl_out (hwo, op);
    1604     }
    1605 
    1606     while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
    1607         hwi->pcm_ops->ctl_in (hwi, op);
    1608     }
    1609 }
    1610 
    1611 static void audio_atexit (void)
    1612 {
    1613     AudioState *s = &glob_audio_state;
    1614     HWVoiceOut *hwo = NULL;
    1615     HWVoiceIn *hwi = NULL;
    1616 
    1617     /* VBox change: audio_pcm_hw_find_any_enabled_out => audio_pcm_hw_find_any_out */
    1618     while ((hwo = audio_pcm_hw_find_any_out (s, hwo))) {
    1619         SWVoiceCap *sc;
    1620 
    1621         hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
    1622         hwo->pcm_ops->fini_out (hwo);
    1623 
    1624         for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
    1625             CaptureVoiceOut *cap = sc->cap;
    1626             struct capture_callback *cb;
    1627 
    1628             for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
    1629                 cb->ops.destroy (cb->opaque);
    1630             }
    1631         }
    1632     }
    1633 
    1634     /* VBox change: audio_pcm_hw_find_any_enabled_in => audio_pcm_hw_find_any_in */
    1635     while ((hwi = audio_pcm_hw_find_any_in (s, hwi))) {
    1636         hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
    1637         hwi->pcm_ops->fini_in (hwi);
    1638     }
    1639 
    1640     if (s->drv) {
    1641         s->drv->fini (s->drv_opaque);
    1642     }
    1643 }
    1644 
    1645 void AUD_register_card (const char *name, QEMUSoundCard *card)
    1646 {
    1647     AudioState *s = &glob_audio_state;
    1648     card->audio = s;
    1649     card->name = qemu_strdup (name);
    1650     memset (&card->entries, 0, sizeof (card->entries));
    1651     LIST_INSERT_HEAD (&s->card_head, card, entries);
    1652 }
    1653 
    1654 void AUD_remove_card (QEMUSoundCard *card)
    1655 {
    1656     LIST_REMOVE (card, entries);
    1657     card->audio = NULL;
    1658     qemu_free (card->name);
    1659 }
    1660 
    1661 static DECLCALLBACK(void) audio_timer_helper (PPDMDRVINS pDrvIns, PTMTIMER pTimer, void *pvUser)
    1662 {
    1663     AudioState *s = (AudioState *)pvUser;
    1664     audio_timer (s);
    1665 }
    1666 
    1667 static int AUD_init (PCFGMNODE pCfgHandle, PPDMDRVINS pDrvIns, const char *drvname)
    1668 {
    1669     size_t i;
    1670     int done = 0;
    1671     AudioState *s = &glob_audio_state;
    1672     int rc;
    1673 
    1674     LIST_INIT (&s->hw_head_out);
    1675     LIST_INIT (&s->hw_head_in);
    1676     LIST_INIT (&s->cap_head);
    1677 
    1678     rc = PDMDrvHlpTMTimerCreate (pDrvIns, TMCLOCK_VIRTUAL, audio_timer_helper,
    1679                                  &glob_audio_state, 0, "Audio timer", &s->ts);
    1680     if (RT_FAILURE (rc))
    1681         return rc;
    1682 
    1683     audio_process_options (pCfgHandle, "AUDIO", audio_options);
    1684 
    1685     s->nb_hw_voices_out = conf.fixed_out.nb_voices;
    1686     s->nb_hw_voices_in = conf.fixed_in.nb_voices;
    1687 
    1688     if (s->nb_hw_voices_out <= 0) {
    1689         dolog ("Bogus number of playback voices %d, setting to 1\n",
    1690                s->nb_hw_voices_out);
    1691         s->nb_hw_voices_out = 1;
    1692     }
    1693 
    1694     if (s->nb_hw_voices_in <= 0) {
    1695         dolog ("Bogus number of capture voices %d, setting to 0\n",
    1696                s->nb_hw_voices_in);
    1697         s->nb_hw_voices_in = 0;
    1698     }
    1699 
    1700     LogRel(("Audio: Trying driver '%s'.\n", drvname));
    1701 
    1702     if (drvname) {
    1703         int found = 0;
    1704 
    1705         for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
    1706             if (!strcmp (drvname, drvtab[i]->name)) {
    1707                 done = !audio_driver_init (pCfgHandle, s, drvtab[i]);
    1708                 found = 1;
    1709                 break;
    1710             }
    1711         }
    1712 
    1713         if (!found) {
    1714             dolog ("Unknown audio driver `%s'\n", drvname);
    1715         }
    1716     }
    1717 
    1718     if (!done) {
    1719         for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
    1720             if (drvtab[i]->can_be_default) {
    1721                 LogRel(("Audio: Initialization of driver '%s' failed, trying '%s'.\n",
    1722                        drvname, drvtab[i]->name));
    1723                 drvname = drvtab[i]->name;
    1724                 done = !audio_driver_init (pCfgHandle, s, drvtab[i]);
    1725             }
    1726         }
    1727     }
    1728 
    1729     if (!done) {
    1730         done = !audio_driver_init (pCfgHandle, s, &no_audio_driver);
    1731         if (!done) {
    1732             dolog ("Could not initialize audio subsystem\n");
    1733         }
    1734         else {
    1735             LogRel(("Audio: Initialization of driver '%s' failed, using NULL driver.\n", drvname));
    1736             dolog ("warning: Using timer based audio emulation\n");
    1737         }
    1738     }
    1739 
    1740     if (done) {
    1741         if (conf.period.hz <= 0) {
    1742             if (conf.period.hz < 0) {
    1743                 dolog ("warning: Timer period is negative - %d "
    1744                        "treating as zero\n",
    1745                        conf.period.hz);
    1746             }
    1747             conf.period.ticks = 1;
    1748         }
    1749         else {
    1750             conf.period.ticks = PDMDrvHlpTMGetVirtualFreq (pDrvIns)
    1751                 / conf.period.hz;
    1752         }
    1753     }
    1754     else {
    1755         /* XXX */
    1756         rc = TMR3TimerDestroy (s->ts);
    1757         return rc;
    1758     }
    1759 
    1760     LIST_INIT (&s->card_head);
    1761     TMTimerSet (s->ts, TMTimerGet (s->ts) + conf.period.ticks);
    1762     return VINF_SUCCESS;
    1763 }
    1764 
    1765 int AUD_init_null(void)
    1766 {
    1767     AudioState *s = &glob_audio_state;
    1768 
    1769 #ifdef VBOX
    1770     if (s->drv)
    1771         s->drv->fini (s->drv_opaque);
    1772 #endif
    1773 
    1774     LogRel(("Audio: Using NULL audio driver\n"));
    1775     return audio_driver_init (NULL, s, &no_audio_driver);
    1776 }
    1777 
    1778 CaptureVoiceOut *AUD_add_capture (
    1779     AudioState *s,
    1780     audsettings_t *as,
    1781     struct audio_capture_ops *ops,
    1782     void *cb_opaque
    1783     )
    1784 {
    1785     CaptureVoiceOut *cap;
    1786     struct capture_callback *cb;
    1787 
    1788     if (!s) {
    1789         /* XXX suppress */
    1790         s = &glob_audio_state;
    1791     }
    1792 
    1793     if (audio_validate_settings (as)) {
    1794         dolog ("Invalid settings were passed when trying to add capture\n");
    1795         audio_print_settings (as);
    1796         goto err0;
    1797     }
    1798 
    1799     cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
    1800     if (!cb) {
    1801         dolog ("Could not allocate capture callback information, size %u\n",
    1802                sizeof (*cb));
    1803         goto err0;
    1804     }
    1805     cb->ops = *ops;
    1806     cb->opaque = cb_opaque;
    1807 
    1808     cap = audio_pcm_capture_find_specific (s, as);
    1809     if (cap) {
    1810         LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
    1811         return cap;
    1812     }
    1813     else {
    1814         HWVoiceOut *hw;
    1815 #ifndef VBOX
    1816         CaptureVoiceOut *cap;
    1817 #endif
    1818 
    1819         cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
    1820         if (!cap) {
    1821             dolog ("Could not allocate capture voice, size %u\n",
    1822                    sizeof (*cap));
    1823             goto err1;
    1824         }
    1825 
    1826         hw = &cap->hw;
    1827         LIST_INIT (&hw->sw_head);
    1828         LIST_INIT (&cap->cb_head);
    1829 
    1830         /* XXX find a more elegant way */
    1831         hw->samples = 4096 * 4;
    1832         hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
    1833                                     sizeof (st_sample_t));
    1834         if (!hw->mix_buf) {
    1835             dolog ("Could not allocate capture mix buffer (%d samples)\n",
    1836                    hw->samples);
    1837             goto err2;
    1838         }
    1839 
    1840         audio_pcm_init_info (&hw->info, as);
    1841 
    1842         cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
    1843         if (!cap->buf) {
    1844             dolog ("Could not allocate capture buffer "
    1845                    "(%d samples, each %d bytes)\n",
    1846                    hw->samples, 1 << hw->info.shift);
    1847             goto err3;
    1848         }
    1849 
    1850         hw->clip = mixeng_clip
    1851             [hw->info.nchannels == 2]
    1852             [hw->info.sign]
    1853             [hw->info.swap_endianness]
    1854             [audio_bits_to_index (hw->info.bits)];
    1855 
    1856         LIST_INSERT_HEAD (&s->cap_head, cap, entries);
    1857         LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
    1858 
    1859         hw = NULL;
    1860         while ((hw = audio_pcm_hw_find_any_out (s, hw))) {
    1861             audio_attach_capture (s, hw);
    1862         }
    1863         return cap;
    1864 
    1865     err3:
    1866         qemu_free (cap->hw.mix_buf);
    1867     err2:
    1868         qemu_free (cap);
    1869     err1:
    1870         qemu_free (cb);
    1871     err0:
    1872         return NULL;
    1873     }
    1874 }
    1875 
    1876 void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
    1877 {
    1878     struct capture_callback *cb;
    1879 
    1880     for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
    1881         if (cb->opaque == cb_opaque) {
    1882             cb->ops.destroy (cb_opaque);
    1883             LIST_REMOVE (cb, entries);
    1884             qemu_free (cb);
    1885 
    1886             if (!cap->cb_head.lh_first) {
    1887                 SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
    1888 
    1889                 while (sw) {
    1890                     SWVoiceCap *sc = (SWVoiceCap *) sw;
    1891 #ifdef DEBUG_CAPTURE
    1892                     dolog ("freeing %s\n", sw->name);
    1893 #endif
    1894 
    1895                     sw1 = sw->entries.le_next;
    1896                     if (sw->rate) {
    1897                         st_rate_stop (sw->rate);
    1898                         sw->rate = NULL;
    1899                     }
    1900                     LIST_REMOVE (sw, entries);
    1901                     LIST_REMOVE (sc, entries);
    1902                     qemu_free (sc);
    1903                     sw = sw1;
    1904                 }
    1905                 LIST_REMOVE (cap, entries);
    1906                 qemu_free (cap);
    1907             }
    1908             return;
    1909         }
    1910     }
    1911 }
    1912 
    1913 void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol)
    1914 {
    1915     if (sw)
    1916     {
    1917         sw->vol.mute = mute;
    1918         sw->vol.l    = (uint32_t)lvol * 0x808080; /* maximum is INT_MAX = 0x7fffffff */
    1919         sw->vol.r    = (uint32_t)rvol * 0x808080; /* maximum is INT_MAX = 0x7fffffff */
    1920     }
    1921 }
    1922 
    1923 void AUD_set_volume (audmixerctl_t mt, int *mute, uint8_t *lvol, uint8_t *rvol)
    1924 {
    1925     volume_t *vol = NULL;
    1926     const char *name;
    1927 
    1928     switch (mt)
    1929     {
    1930         case AUD_MIXER_VOLUME:
    1931             name = "MASTER";
    1932             vol  = &master_out_volume;
    1933             break;
    1934         case AUD_MIXER_PCM:
    1935             name = "PCM_OUT";
    1936             vol  = &pcm_out_volume;
    1937             break;
    1938         case AUD_MIXER_LINE_IN:
    1939             name = "LINE_IN";
    1940             vol  = &pcm_in_volume;
    1941             break;
    1942         default:
    1943             return;
    1944 
    1945     }
    1946 
    1947     if (vol)
    1948     {
    1949         uint32_t u32VolumeLeft  = (uint32_t)*lvol;
    1950         uint32_t u32VolumeRight = (uint32_t)*rvol;
    1951         /* 0x00..0xff => 0x01..0x100 */
    1952         if (u32VolumeLeft)
    1953             u32VolumeLeft++;
    1954         if (u32VolumeRight)
    1955             u32VolumeRight++;
    1956         vol->mute  = *mute;
    1957         vol->l     = u32VolumeLeft  * 0x800000; /* maximum is 0x80000000 */
    1958         vol->r     = u32VolumeRight * 0x800000; /* maximum is 0x80000000 */
    1959     }
    1960     sum_out_volume.mute = master_out_volume.mute || pcm_out_volume.mute;
    1961     sum_out_volume.l    = ASMMultU64ByU32DivByU32(master_out_volume.l, pcm_out_volume.l, 0x80000000U);
    1962     sum_out_volume.r    = ASMMultU64ByU32DivByU32(master_out_volume.r, pcm_out_volume.r, 0x80000000U);
    1963 }
    1964 
    1965 void AUD_set_record_source (audrecsource_t *ars, audrecsource_t *als)
    1966 {
    1967     LogRel(("Audio: set_record_source ars=%d als=%d (not implemented)\n", *ars, *als));
    1968 }
    1969 
    1970 int AUD_is_host_voice_in_ok(SWVoiceIn *sw)
    1971 {
    1972     AudioState *s = &glob_audio_state;
    1973 
     2173        sw->State.fActive = on;
     2174    }
     2175}
     2176
     2177static DECLCALLBACK(int) drvAudioIsHostVoiceInOK(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN sw)
     2178{
    19742179    if (sw == NULL) {
    19752180        return 0;
    19762181    }
    1977 
    1978     return filteraudio_is_host_voice_in_ok(s->drv, sw->hw);
    1979 }
    1980 
    1981 int AUD_is_host_voice_out_ok(SWVoiceOut *sw)
    1982 {
    1983     AudioState *s = &glob_audio_state;
    1984 
     2182    return 1;
     2183}
     2184
     2185static DECLCALLBACK(int) drvAudioIsHostVoiceOutOK(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT sw)
     2186{
    19852187    if (sw == NULL) {
    19862188        return 0;
    19872189    }
    1988 
    1989     return filteraudio_is_host_voice_out_ok(s->drv, sw->hw);
    1990 }
     2190    return 1;
     2191}
     2192
     2193static DECLCALLBACK(int) drvAudioOpenIn(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN *ppGstVoiceIn,
     2194                                        const char *name, void *callback_opaque , audio_callback_fn_t callback_fn,
     2195                                        uint32_t uFrequency, uint32_t cChannels, audfmt_e Format, uint32_t Endian)
     2196{
     2197    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     2198    audsettings_t AudioSettings;
     2199    AudioSettings.freq = uFrequency;
     2200    AudioSettings.nchannels = cChannels;
     2201    AudioSettings.fmt = Format;
     2202    AudioSettings.endianness = Endian;
     2203    LogFlow(("DrvAudio: open IN %s, freq %d, nchannels %d, fmt %d\n",
     2204             name, AudioSettings.freq, AudioSettings.nchannels, AudioSettings.fmt));
     2205
     2206    if (drvAudioValidateSettings(&AudioSettings))
     2207    {
     2208        LogRel(("Audio: Audio Settings Validation failed \n"));
     2209        drvAudioPrintSettings(&AudioSettings);
     2210        drvAudioHlpCloseIn(pThis, &pThis->qemuSoundCard, *ppGstVoiceIn);
     2211        *ppGstVoiceIn = (PPDMGSTVOICEIN)NULL;
     2212        return VERR_GENERAL_FAILURE;
     2213    }
     2214
     2215    if (*ppGstVoiceIn && drvAudioPcmInfoEq(&(*ppGstVoiceIn)->Props, &AudioSettings))
     2216        return VINF_SUCCESS;
     2217
     2218    if (!conf.fixed_in.enabled && *ppGstVoiceIn)
     2219    {
     2220        drvAudioHlpCloseIn(pThis, &pThis->qemuSoundCard, *ppGstVoiceIn);
     2221        *ppGstVoiceIn = (PPDMGSTVOICEIN )NULL;
     2222    }
     2223
     2224    if (*ppGstVoiceIn)
     2225    {
     2226        PPDMHOSTVOICEIN pHostVoiceIn = (*ppGstVoiceIn)->hw;
     2227
     2228        if (!pHostVoiceIn)
     2229        {
     2230            LogFlow(("Internal logic error voice has no hardware store\n"));
     2231            drvAudioHlpCloseIn(pThis, &pThis->qemuSoundCard, *ppGstVoiceIn);
     2232            *ppGstVoiceIn = (PPDMGSTVOICEIN)NULL;
     2233            return VERR_GENERAL_FAILURE;
     2234        }
     2235
     2236        drvAudioHlpPcmSwFinishedIn(*ppGstVoiceIn);
     2237        if (drvAudioHlpPcmSwInitIn(*ppGstVoiceIn, pHostVoiceIn, name, &AudioSettings))
     2238        {
     2239            drvAudioHlpCloseIn(pThis, &pThis->qemuSoundCard, *ppGstVoiceIn);
     2240            *ppGstVoiceIn = (PPDMGSTVOICEIN)NULL;
     2241            return VERR_GENERAL_FAILURE;
     2242        }
     2243    }
     2244    else
     2245    {
     2246        *ppGstVoiceIn = drvAudioHlpPcmCreateVoicePairIn(pThis, name, &AudioSettings);
     2247        if (!(*ppGstVoiceIn))
     2248        {
     2249            LogFlow(("Failed to create voice `%s'\n", name));
     2250            *ppGstVoiceIn = (PPDMGSTVOICEIN)NULL;
     2251            return VERR_GENERAL_FAILURE;
     2252        }
     2253    }
     2254
     2255    if (*ppGstVoiceIn)
     2256    {
     2257        (*ppGstVoiceIn)->State.uVolumeLeft = nominal_volume.l;
     2258        (*ppGstVoiceIn)->State.uVolumeRight = nominal_volume.r;
     2259        (*ppGstVoiceIn)->State.uVolumeMute = nominal_volume.mute;
     2260        (*ppGstVoiceIn)->callback.fn = callback_fn;
     2261        (*ppGstVoiceIn)->callback.opaque = callback_opaque;
     2262    }
     2263    return VINF_SUCCESS;
     2264}
     2265
     2266
     2267static DECLCALLBACK(int) drvAudioOpenOut(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT *ppGstVoiceOut, const char *name,
     2268                                         void *callback_opaque, audio_callback_fn_t callback_fn,
     2269                                         uint32_t uFrequency, uint32_t cChannels, audfmt_e Format, uint32_t Endian)
     2270{
     2271    int cLiveSamples = 0;
     2272    AudioState *s;
     2273    int rc;
     2274    PPDMGSTVOICEOUT pOldGstVoiceOut;
     2275    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     2276    audsettings_t AudioSettings;
     2277    AudioSettings.freq = uFrequency;
     2278    AudioSettings.nchannels = cChannels;
     2279    AudioSettings.fmt = Format;
     2280    AudioSettings.endianness = Endian;
     2281
     2282    LogFlow(("DrvAudio: open OUT %s, freq %d, nchannels %d, fmt %d\n",
     2283            name, AudioSettings.freq, AudioSettings.nchannels, AudioSettings.fmt));
     2284
     2285    if (drvAudioValidateSettings(&AudioSettings))
     2286    {
     2287        LogRel(("DrvAudio: Audio Settings Validation failed \n"));
     2288        drvAudioPrintSettings(&AudioSettings);
     2289        drvAudioHlpCloseOut(pThis, &pThis->qemuSoundCard, *ppGstVoiceOut);
     2290        *ppGstVoiceOut = (PPDMGSTVOICEOUT)NULL;
     2291        return VERR_GENERAL_FAILURE;
     2292    }
     2293
     2294    if (*ppGstVoiceOut && drvAudioPcmInfoEq(&(*ppGstVoiceOut)->Props, &AudioSettings))
     2295        return VINF_SUCCESS;
     2296
     2297    if (  conf.plive && *ppGstVoiceOut
     2298        && (!(*ppGstVoiceOut)->State.fActive
     2299        && !(*ppGstVoiceOut)->State.fEmpty)
     2300       )
     2301    {
     2302        cLiveSamples = (*ppGstVoiceOut)->cSamplesMixed;
     2303        if(cLiveSamples)
     2304        {
     2305            pOldGstVoiceOut = *ppGstVoiceOut;
     2306            *ppGstVoiceOut = NULL;
     2307        }
     2308    }
     2309
     2310    if (!conf.fixed_out.enabled && *ppGstVoiceOut)
     2311    {
     2312        drvAudioHlpCloseOut(pThis, &pThis->qemuSoundCard, *ppGstVoiceOut);
     2313        *ppGstVoiceOut = (PPDMGSTVOICEOUT *)NULL;
     2314    }
     2315
     2316    if (*ppGstVoiceOut)
     2317    {
     2318        PPDMHOSTVOICEOUT pHostVoiceOut = (*ppGstVoiceOut)->pHostVoiceOut;
     2319        if (!pHostVoiceOut)
     2320        {
     2321            LogFlow(("Guest Voice Stream has no Host voice stream in store\n"));
     2322            return VERR_GENERAL_FAILURE;
     2323        }
     2324
     2325        drvAudioHlpPcmSwFinishedOut(*ppGstVoiceOut);
     2326        rc = drvAudioHlpPcmSwInitOut(*ppGstVoiceOut, pHostVoiceOut, name, &AudioSettings);
     2327        if (RT_FAILURE(rc))
     2328            return rc;
     2329    }
     2330    else
     2331    {
     2332        (*ppGstVoiceOut) = drvAudioHlpPcmCreateVoicePairOut(pThis, s, name, &AudioSettings);
     2333        if (!(*ppGstVoiceOut))
     2334        {
     2335            LogFlow(("Failed to create voice `%s'\n", name));
     2336            *ppGstVoiceOut = (PPDMGSTVOICEOUT)NULL;
     2337            return VERR_GENERAL_FAILURE;
     2338        }
     2339    }
     2340
     2341    if (*ppGstVoiceOut)
     2342    {
     2343        (*ppGstVoiceOut)->State.uVolumeLeft = nominal_volume.l;
     2344        (*ppGstVoiceOut)->State.uVolumeRight = nominal_volume.r;
     2345        (*ppGstVoiceOut)->State.uVolumeMute = nominal_volume.mute;
     2346        (*ppGstVoiceOut)->callback.fn = callback_fn;
     2347        (*ppGstVoiceOut)->callback.opaque = callback_opaque;
     2348        if (cLiveSamples)
     2349        {
     2350            int mixed =
     2351                (cLiveSamples << pOldGstVoiceOut->Props.cShift)
     2352                * pOldGstVoiceOut->Props.cbPerSec
     2353                / (*ppGstVoiceOut)->Props.cbPerSec;
     2354
     2355            (*ppGstVoiceOut)->cSamplesMixed += mixed;
     2356        }
     2357    }
     2358
     2359    return VINF_SUCCESS;
     2360}
     2361
     2362static DECLCALLBACK(int) drvAudioIsActiveIn(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN pGstVoiceIn)
     2363{
     2364    return pGstVoiceIn ? pGstVoiceIn->State.fActive : 0;
     2365}
     2366
     2367static DECLCALLBACK(int) drvAudioIsActiveOut(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT pGstVoiceOut)
     2368{
     2369    return pGstVoiceOut ? pGstVoiceOut->State.fActive : 0;
     2370}
     2371
     2372static DECLCALLBACK(t_sample *)drvAudioConvDevFmtToStSample(PPDMIAUDIOCONNECTOR pInterface, uint32_t cChannels,
     2373                                                     uint32_t fSign, uint32_t uEndian, uint32_t ubitIdx)
     2374{
     2375    LogFlow(("DrvAudio: drvAudioConvStSamplToFmt \n"));
     2376    return   mixeng_conv[cChannels] /* stereo */
     2377                         [fSign]     /* sign */
     2378                         [uEndian]   /* big endian */
     2379                         [ubitIdx];  /* bits */
     2380
     2381}
     2382
     2383static DECLCALLBACK(f_sample *)drvAudioConvStSampleToDevFmt(PPDMIAUDIOCONNECTOR pInterface, void *buf,
     2384                                                            PPDMHOSTSTEREOSAMPLE pSampleBuf, uint32_t samples)
     2385{
     2386    /*@todo handle ths properly*/
     2387    clipAudioIn (buf, pSampleBuf, samples);
     2388}
     2389
     2390
     2391static DECLCALLBACK(void *)drvAudioPrepareAudioConversion(PPDMIAUDIOCONNECTOR pInterface, uint32_t uSampleFreq, uint32_t uTgtFreq)
     2392{
     2393    return st_rate_start (uSampleFreq, uTgtFreq);
     2394}
     2395
     2396static DECLCALLBACK(void)drvAudioEndAudioConversion(PPDMIAUDIOCONNECTOR pInterface, void * pRate)
     2397{
     2398    AssertPtr(pRate);
     2399    st_rate_stop (pRate);
     2400}
     2401
     2402static DECLCALLBACK(void)drvAudioDoRateConversion(PPDMIAUDIOCONNECTOR pInterface, void * pRate,
     2403                                                  PPDMHOSTSTEREOSAMPLE pHostStereoSampleBuf,
     2404                                                  PPDMHOSTSTEREOSAMPLE pConvertedSampleBuf,
     2405                                                  uint32_t * pcSampleSrc, uint32_t *pcConvertedSamples)
     2406{
     2407    AssertPtr(pRate);
     2408    st_rate_flow(pRate, pHostStereoSampleBuf, pConvertedSampleBuf, pcSampleSrc, pcConvertedSamples);
     2409
     2410}
     2411
     2412static DECLCALLBACK(void)drvAudioDoRateConvAndMix(PPDMIAUDIOCONNECTOR pInterface, void * pRate,
     2413                                                  PPDMHOSTSTEREOSAMPLE pSourceSampleBuf,
     2414                                                  PPDMHOSTSTEREOSAMPLE pTargetMixedSampleBuf,
     2415                                                  uint32_t * pcSampleSrc, uint32_t *pcMixedSamples)
     2416{
     2417    st_rate_flow_mix(pRate, pSourceSampleBuf, pTargetMixedSampleBuf, pcSampleSrc, pcMixedSamples);
     2418
     2419}
     2420
     2421/****************************************************************/
     2422
     2423static DECLCALLBACK(void) drvAudioCloseIn(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN pGstVoiceIn)
     2424{
     2425    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     2426    if (pGstVoiceIn)
     2427    {
     2428        if (!&pThis->qemuSoundCard || !pThis->qemuSoundCard.audio)
     2429        {
     2430            LogFlow(("DrvAudio: Error, card=%p card->audio=%p\n",
     2431                   (void *) &pThis->qemuSoundCard, &pThis->qemuSoundCard ? (void *) pThis->qemuSoundCard.audio : NULL));
     2432            return;
     2433        }
     2434        drvAudioHlpCloseIn(pThis, pThis->qemuSoundCard.audio, pGstVoiceIn);
     2435    }
     2436}
     2437
     2438DECLCALLBACK(void) drvAudioCloseOut(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT pGstVoiceOut)
     2439{
     2440    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     2441    if (pGstVoiceOut) {
     2442        if (!&pThis->qemuSoundCard || !pThis->qemuSoundCard.audio)
     2443        {
     2444            LogFlow(("DrvAudio: Error, card=%p card->audio=%p\n",
     2445                   (void *) &pThis->qemuSoundCard, &pThis->qemuSoundCard ? (void *) pThis->qemuSoundCard.audio : NULL));
     2446            return;
     2447        }
     2448
     2449        drvAudioHlpCloseOut(pThis, pThis->qemuSoundCard.audio, pGstVoiceOut);
     2450    }
     2451}
     2452
     2453
     2454/********************************************************************/
     2455
     2456
    19912457
    19922458/**
     
    20092475static DECLCALLBACK(void) drvAudioPowerOff(PPDMDRVINS pDrvIns)
    20102476{
    2011     AudioState *s = &glob_audio_state;
    2012     audio_vm_change_state_handler (s, 0);
     2477    audio_vm_change_state_handler (pDrvIns, 0);
    20132478}
    20142479
     
    20312496        audio_streamname = NULL;
    20322497    }
    2033 
    2034     audio_atexit ();
    2035 }
     2498    drvAudioExit(pDrvIns);
     2499}
     2500
    20362501
    20372502/**
     
    20442509    PDRVAUDIO   pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO);
    20452510    char       *drvname;
    2046     int         rc;
    2047 
    2048     LogFlow(("drvAUDIOConstruct:\n"));
     2511    int         rc = 0;
     2512    PPDMIBASE pBase;
     2513
    20492514    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    2050 
    2051     /*
    2052      * Validate the config.
    2053      */
    2054     if (!CFGMR3AreValuesValid(pCfgHandle, "AudioDriver\0StreamName\0"))
    2055         return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
    20562515
    20572516    /*
     
    20622521    pDrvIns->IBase.pfnQueryInterface  = drvAudioQueryInterface;
    20632522    /* IAudio */
    2064     /* pThis->IAudioConnector.pfn; */
    2065 
    2066     glob_audio_state.pDrvIns = pDrvIns;
    2067 
     2523    pThis->IAudioConnector.pfnRead             = drvAudioRead;
     2524    pThis->IAudioConnector.pfnWrite            = drvAudioWrite;
     2525    pThis->IAudioConnector.pfnRegisterCard     = drvAudioRegisterCard;
     2526    pThis->IAudioConnector.pfnIsHostVoiceInOK  = drvAudioIsHostVoiceInOK;
     2527    pThis->IAudioConnector.pfnIsHostVoiceOutOK = drvAudioIsHostVoiceOutOK;
     2528    pThis->IAudioConnector.pfnInitNull         = drvAudioInitNull;
     2529    pThis->IAudioConnector.pfnIsSetOutVolume   = drvAudioIsSetOutVolume;
     2530    pThis->IAudioConnector.pfnSetVolume        = drvAudioSetVolume;
     2531    pThis->IAudioConnector.pfnEnableOut        = drvAudioEnableOut;
     2532    pThis->IAudioConnector.pfnEnableIn         = drvAudioEnableIn;
     2533    pThis->IAudioConnector.pfnCloseIn          = drvAudioCloseIn;
     2534    pThis->IAudioConnector.pfnCloseOut         = drvAudioCloseOut;
     2535    pThis->IAudioConnector.pfnOpenIn           = drvAudioOpenIn;
     2536    pThis->IAudioConnector.pfnOpenOut          = drvAudioOpenOut;
     2537    pThis->IAudioConnector.pfnIsActiveIn       = drvAudioIsActiveIn;
     2538    pThis->IAudioConnector.pfnIsActiveOut      = drvAudioIsActiveOut;
     2539    /* Mixer/Conversion */
     2540    pThis->IAudioConnector.pfnConvDevFmtToStSample   = drvAudioConvDevFmtToStSample;
     2541    pThis->IAudioConnector.pfnConvStSampleToDevFmt   = drvAudioConvStSampleToDevFmt;
     2542    pThis->IAudioConnector.pfnPrepareAudioConversion = drvAudioPrepareAudioConversion;
     2543    pThis->IAudioConnector.pfnEndAudioConversion     = drvAudioEndAudioConversion;
     2544    pThis->IAudioConnector.pfnDoRateConversion       = drvAudioDoRateConversion;
     2545    pThis->IAudioConnector.pfnDoRateConvAndMix       = drvAudioDoRateConvAndMix;
     2546
     2547    rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBase);
     2548    if (RT_FAILURE(rc))
     2549    {
     2550        LogRel(("Failed to attach  the audio device rc = %d \n", rc));
     2551        return rc;
     2552    }
     2553    pThis->pHostDrvAudio = PDMIBASE_QUERY_INTERFACE(pBase, PDMIHOSTAUDIO);
     2554    if (!pThis->pHostDrvAudio)
     2555    {
     2556        LogRel(("Audio: Failed to attach to underlying host driver \n"));
     2557        return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW,
     2558                                N_("No media or async media interface below"));
     2559    }
     2560
     2561    pThis->pDrvIns = pDrvIns;
     2562    gpDrvIns = pThis->pDrvIns;
    20682563    rc = CFGMR3QueryStringAlloc (pCfgHandle, "AudioDriver", &drvname);
    20692564    if (RT_FAILURE (rc))
     2565    {
     2566        LogFlow(("Failed to get AudioDriver from CFGM\n"));
    20702567        return rc;
     2568    }
    20712569
    20722570    rc = CFGMR3QueryStringAlloc (pCfgHandle, "StreamName", &audio_streamname);
    20732571    if (RT_FAILURE (rc))
     2572    {
     2573        LogFlow(("Failed to get SteamName from CFGM \n"));
    20742574        audio_streamname = NULL;
    2075 
    2076     rc = AUD_init (pCfgHandle, pDrvIns, drvname);
     2575    }
     2576    rc = drvAudioInit(pCfgHandle, pDrvIns, drvname, pThis);
    20772577    if (RT_FAILURE (rc))
    20782578        return rc;
     
    20912591static DECLCALLBACK(void) drvAudioSuspend(PPDMDRVINS pDrvIns)
    20922592{
    2093     AudioState *s = &glob_audio_state;
    2094     audio_vm_change_state_handler (s, 0);
     2593    audio_vm_change_state_handler(pDrvIns, 0);
    20952594}
    20962595
     
    21032602static DECLCALLBACK(void) audioResume(PPDMDRVINS pDrvIns)
    21042603{
    2105     AudioState *s = &glob_audio_state;
    2106     audio_vm_change_state_handler (s, 1);
     2604    audio_vm_change_state_handler(pDrvIns, 1);
    21072605}
    21082606
     
    21272625    PDM_DRVREG_CLASS_AUDIO,
    21282626    /* cMaxInstances */
    2129     1,
     2627    2,
    21302628    /* cbInstance */
    21312629    sizeof(DRVAUDIO),
     
    21582656};
    21592657
     2658
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