VirtualBox

Changeset 88451 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Apr 9, 2021 10:34:33 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
143703
Message:

DrvHostAlsaAudio: Implemented basic device enumeration. bugref:9890

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp

    r88450 r88451  
    5151#include <VBox/vmm/pdmaudioifs.h>
    5252#include <VBox/vmm/pdmaudioinline.h>
     53#include <VBox/vmm/pdmaudiohostenuminline.h>
    5354
    5455RT_C_DECLS_BEGIN
     
    6465
    6566/*********************************************************************************************************************************
     67*   Defined Constants And Macros                                                                                                 *
     68*********************************************************************************************************************************/
     69/** Maximum number of tries to recover a broken pipe. */
     70#define ALSA_RECOVERY_TRIES_MAX    5
     71
     72
     73/*********************************************************************************************************************************
    6674*   Structures                                                                                                                   *
    6775*********************************************************************************************************************************/
    68 /**
    69  * Structure for maintaining an ALSA audio stream.
    70  */
    71 typedef struct ALSAAUDIOSTREAM
    72 {
    73     /** The stream's acquired configuration. */
    74     PPDMAUDIOSTREAMCFG pCfg;
    75     /** Pointer to allocated ALSA PCM configuration to use. */
    76     snd_pcm_t          *phPCM;
    77     /** Internal stream offset (for debugging). */
    78     uint64_t            offInternal;
    79 } ALSAAUDIOSTREAM, *PALSAAUDIOSTREAM;
    80 
    81 /* latency = period_size * periods / (rate * bytes_per_frame) */
    82 
    83 static int alsaStreamRecover(snd_pcm_t *phPCM);
    84 
    85 /**
    86  * Host Alsa audio driver instance data.
    87  * @implements PDMIAUDIOCONNECTOR
    88  */
    89 typedef struct DRVHOSTALSAAUDIO
    90 {
    91     /** Pointer to the driver instance structure. */
    92     PPDMDRVINS          pDrvIns;
    93     /** Pointer to host audio interface. */
    94     PDMIHOSTAUDIO       IHostAudio;
    95     /** Error count for not flooding the release log.
    96      *  UINT32_MAX for unlimited logging. */
    97     uint32_t            cLogErrors;
    98     /** Default input device name.   */
    99     char                szDefaultIn[256];
    100     /** Default output device name. */
    101     char                szDefaultOut[256];
    102 } DRVHOSTALSAAUDIO, *PDRVHOSTALSAAUDIO;
    103 
    104 /** Maximum number of tries to recover a broken pipe. */
    105 #define ALSA_RECOVERY_TRIES_MAX    5
    106 
    10776/**
    10877 * Structure for maintaining an ALSA audio stream configuration.
     
    12392    /** Periods (in audio frames). */
    12493    unsigned long       period_size;
    125     /** For playback: Starting to play threshold (in audio frames).
     94    /** For playback:  Starting to play threshold (in audio frames).
    12695     *  For Capturing: Starting to capture threshold (in audio frames). */
    12796    unsigned long       threshold;
     97
     98    /* latency = period_size * periods / (rate * bytes_per_frame) */
    12899} ALSAAUDIOSTREAMCFG, *PALSAAUDIOSTREAMCFG;
     100
     101/**
     102 * Structure for maintaining an ALSA audio stream.
     103 */
     104typedef struct ALSAAUDIOSTREAM
     105{
     106    /** The stream's acquired configuration. */
     107    PPDMAUDIOSTREAMCFG  pCfg;
     108    /** Pointer to allocated ALSA PCM configuration to use. */
     109    snd_pcm_t          *hPCM;
     110    /** Internal stream offset (for debugging). */
     111    uint64_t            offInternal;
     112} ALSAAUDIOSTREAM, *PALSAAUDIOSTREAM;
     113
     114
     115/**
     116 * Host Alsa audio driver instance data.
     117 * @implements PDMIAUDIOCONNECTOR
     118 */
     119typedef struct DRVHOSTALSAAUDIO
     120{
     121    /** Pointer to the driver instance structure. */
     122    PPDMDRVINS          pDrvIns;
     123    /** Pointer to host audio interface. */
     124    PDMIHOSTAUDIO       IHostAudio;
     125    /** Error count for not flooding the release log.
     126     *  UINT32_MAX for unlimited logging. */
     127    uint32_t            cLogErrors;
     128    /** Default input device name.   */
     129    char                szDefaultIn[256];
     130    /** Default output device name. */
     131    char                szDefaultOut[256];
     132} DRVHOSTALSAAUDIO, *PDRVHOSTALSAAUDIO;
    129133
    130134
     
    173177 *
    174178 * @returns VBox status code.
    175  * @param   phPCM               ALSA stream handle.
    176  */
    177 static int alsaStreamRecover(snd_pcm_t *phPCM)
    178 {
    179     AssertPtrReturn(phPCM, VERR_INVALID_POINTER);
    180 
    181     int err = snd_pcm_prepare(phPCM);
     179 * @param   hPCM               ALSA stream handle.
     180 */
     181static int alsaStreamRecover(snd_pcm_t *hPCM)
     182{
     183    AssertPtrReturn(hPCM, VERR_INVALID_POINTER);
     184
     185    int err = snd_pcm_prepare(hPCM);
    182186    if (err < 0)
    183187    {
    184         LogFunc(("Failed to recover stream %p: %s\n", phPCM, snd_strerror(err)));
     188        LogFunc(("Failed to recover stream %p: %s\n", hPCM, snd_strerror(err)));
    185189        return VERR_ACCESS_DENIED; /** @todo Find a better rc. */
    186190    }
     
    193197 *
    194198 * @returns VBox status code.
    195  * @param   phPCM               ALSA stream to resume.
    196  */
    197 static int alsaStreamResume(snd_pcm_t *phPCM)
    198 {
    199     AssertPtrReturn(phPCM, VERR_INVALID_POINTER);
    200 
    201     int err = snd_pcm_resume(phPCM);
     199 * @param   hPCM               ALSA stream to resume.
     200 */
     201static int alsaStreamResume(snd_pcm_t *hPCM)
     202{
     203    AssertPtrReturn(hPCM, VERR_INVALID_POINTER);
     204
     205    int err = snd_pcm_resume(hPCM);
    202206    if (err < 0)
    203207    {
    204         LogFunc(("Failed to resume stream %p: %s\n", phPCM, snd_strerror(err)));
     208        LogFunc(("Failed to resume stream %p: %s\n", hPCM, snd_strerror(err)));
    205209        return VERR_ACCESS_DENIED; /** @todo Find a better rc. */
    206210    }
     
    218222    AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
    219223
    220     RTStrPrintf2(pBackendCfg->szName, sizeof(pBackendCfg->szName), "ALSA");
    221 
     224    /*
     225     * Fill in the config structure.
     226     */
     227    RTStrCopy(pBackendCfg->szName, sizeof(pBackendCfg->szName), "ALSA");
    222228    pBackendCfg->cbStreamIn  = sizeof(ALSAAUDIOSTREAM);
    223229    pBackendCfg->cbStreamOut = sizeof(ALSAAUDIOSTREAM);
    224 
    225     /* Enumerate sound devices. */
    226     char **pszHints;
    227     int err = snd_device_name_hint(-1 /* All cards */, "pcm", (void***)&pszHints);
    228     if (err == 0)
    229     {
    230         char** pszHintCur = pszHints;
    231         while (*pszHintCur != NULL)
    232         {
    233             char *pszDev = snd_device_name_get_hint(*pszHintCur, "NAME");
    234             bool fSkip =    !pszDev
    235                          || !RTStrICmp("null", pszDev);
    236             if (fSkip)
    237             {
    238                 if (pszDev)
    239                     free(pszDev);
    240                 pszHintCur++;
    241                 continue;
    242             }
    243 
    244             char *pszIOID = snd_device_name_get_hint(*pszHintCur, "IOID");
    245             if (pszIOID)
    246             {
    247 #if 0
    248                 if (!RTStrICmp("input", pszIOID))
    249 
    250                 else if (!RTStrICmp("output", pszIOID))
    251 #endif
    252             }
    253             else /* NULL means bidirectional, input + output. */
    254             {
    255             }
    256 
    257             LogRel2(("ALSA: Found %s device: %s\n", pszIOID ?  RTStrToLower(pszIOID) : "bidirectional", pszDev));
    258 
    259             /* Special case for ALSAAudio. */
    260             if (   pszDev
    261                 && RTStrIStr("pulse", pszDev) != NULL)
    262                 LogRel2(("ALSA: ALSAAudio plugin in use\n"));
    263 
    264             if (pszIOID)
    265                 free(pszIOID);
    266 
    267             if (pszDev)
    268                 free(pszDev);
    269 
    270             pszHintCur++;
    271         }
    272 
    273         snd_device_name_free_hint((void **)pszHints);
    274         pszHints = NULL;
    275     }
    276     else
    277         LogRel2(("ALSA: Error enumerating PCM devices: %Rrc (%d)\n", RTErrConvertFromErrno(err), err));
    278230
    279231    /* ALSA allows exactly one input and one output used at a time for the selected device(s). */
     
    284236}
    285237
     238
     239/**
     240 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetDevices}
     241 */
     242static DECLCALLBACK(int) drvHostAlsaAudioHA_GetDevices(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHOSTENUM pDeviceEnum)
     243{
     244    RT_NOREF(pInterface);
     245    PDMAudioHostEnumInit(pDeviceEnum);
     246
     247    char **papszHints = NULL;
     248    int rc = snd_device_name_hint(-1 /* All cards */, "pcm", (void***)&papszHints);
     249    if (rc == 0)
     250    {
     251        rc = VINF_SUCCESS;
     252        for (size_t iHint = 0; papszHints[iHint] != NULL && RT_SUCCESS(rc); iHint++)
     253        {
     254            /*
     255             * Retrieve the available info:
     256             */
     257            const char * const pszHint = papszHints[iHint];
     258            char * const pszDev     = snd_device_name_get_hint(pszHint, "NAME");
     259            char * const pszInOutId = snd_device_name_get_hint(pszHint, "IOID");
     260            char * const pszDesc    = snd_device_name_get_hint(pszHint, "DESC");
     261
     262            if (pszDev && RTStrICmp(pszDev, "null") != 0)
     263            {
     264                /* Detect and log presence of pulse audio plugin. */
     265                if (RTStrIStr("pulse", pszDev) != NULL)
     266                    LogRel(("ALSA: The ALSAAudio plugin for pulse audio is being used (%s).\n", pszDev));
     267
     268                /*
     269                 * Add an entry to the enumeration result.
     270                 */
     271                PPDMAUDIOHOSTDEV pDev = PDMAudioHostDevAlloc(sizeof(*pDev));
     272                if (pDev)
     273                {
     274                    pDev->fFlags  = PDMAUDIOHOSTDEV_F_NONE;
     275                    pDev->enmType = PDMAUDIODEVICETYPE_UNKNOWN;
     276
     277                    if (pszInOutId == NULL)
     278                    {
     279                        pDev->enmUsage           = PDMAUDIODIR_DUPLEX;
     280                        pDev->cMaxInputChannels  = 2;
     281                        pDev->cMaxOutputChannels = 2;
     282                    }
     283                    else if (RTStrICmp(pszInOutId, "Input") == 0)
     284                    {
     285                        pDev->enmUsage           = PDMAUDIODIR_IN;
     286                        pDev->cMaxInputChannels  = 2;
     287                        pDev->cMaxOutputChannels = 0;
     288                    }
     289                    else
     290                    {
     291                        AssertMsg(RTStrICmp(pszInOutId, "Output") == 0, ("%s (%s)\n", pszInOutId, pszHint));
     292                        pDev->enmUsage = PDMAUDIODIR_OUT;
     293                        pDev->cMaxInputChannels  = 0;
     294                        pDev->cMaxOutputChannels = 2;
     295                    }
     296
     297                    int rc2 = RTStrCopy(pDev->szName, sizeof(pDev->szName), pszDev);
     298                    AssertRC(rc2);
     299
     300                    PDMAudioHostEnumAppend(pDeviceEnum, pDev);
     301
     302                    LogRel2(("ALSA: Device #%u: '%s' enmDir=%s: %s\n", iHint, pszDev,
     303                             PDMAudioDirGetName(pDev->enmUsage), pszDesc));
     304                }
     305                else
     306                    rc = VERR_NO_MEMORY;
     307            }
     308
     309            /*
     310             * Clean up.
     311             */
     312            if (pszInOutId)
     313                free(pszInOutId);
     314            if (pszDesc)
     315                free(pszDesc);
     316            if (pszDev)
     317                free(pszDev);
     318        }
     319
     320        snd_device_name_free_hint((void **)papszHints);
     321
     322        if (RT_FAILURE(rc))
     323        {
     324            PDMAudioHostEnumDelete(pDeviceEnum);
     325            PDMAudioHostEnumInit(pDeviceEnum);
     326        }
     327    }
     328    else
     329    {
     330        int rc2 = RTErrConvertFromErrno(-rc);
     331        LogRel2(("ALSA: Error enumerating PCM devices: %Rrc (%d)\n", rc2, rc));
     332        rc = rc2;
     333    }
     334    return rc;
     335}
    286336
    287337/**
     
    393443 *
    394444 * @returns 0 on success, negative errno on failure.
    395  * @param   phPCM               ALSA stream to set software parameters for.
     445 * @param   hPCM               ALSA stream to set software parameters for.
    396446 * @param   fIn                 Whether this is an input stream or not.
    397447 * @param   pCfgReq             Requested configuration to set.
    398448 * @param   pCfgObt             Obtained configuration on success. Might differ from requested configuration.
    399449 */
    400 static int alsaStreamSetSWParams(snd_pcm_t *phPCM, bool fIn, PALSAAUDIOSTREAMCFG pCfgReq, PALSAAUDIOSTREAMCFG pCfgObt)
     450static int alsaStreamSetSWParams(snd_pcm_t *hPCM, bool fIn, PALSAAUDIOSTREAMCFG pCfgReq, PALSAAUDIOSTREAMCFG pCfgObt)
    401451{
    402452    if (fIn) /* For input streams there's nothing to do in here right now. */
     
    407457    AssertReturn(pSWParms, -ENOMEM);
    408458
    409     int err = snd_pcm_sw_params_current(phPCM, pSWParms);
     459    int err = snd_pcm_sw_params_current(hPCM, pSWParms);
    410460    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to get current software parameters: %s\n", snd_strerror(err)), err);
    411461
     
    420470                 pCfgReq->threshold, cFramesPreBuffer, pCfgObt->buffer_size));
    421471    }
    422     err = snd_pcm_sw_params_set_start_threshold(phPCM, pSWParms, cFramesPreBuffer);
     472    err = snd_pcm_sw_params_set_start_threshold(hPCM, pSWParms, cFramesPreBuffer);
    423473    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set software threshold to %lu: %s\n", cFramesPreBuffer, snd_strerror(err)), err);
    424474
    425     err = snd_pcm_sw_params_set_avail_min(phPCM, pSWParms, pCfgReq->period_size);
     475    err = snd_pcm_sw_params_set_avail_min(hPCM, pSWParms, pCfgReq->period_size);
    426476    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set available minimum to %lu: %s\n", pCfgReq->period_size, snd_strerror(err)), err);
    427477
    428478    /* Commit the software parameters: */
    429     err = snd_pcm_sw_params(phPCM, pSWParms);
     479    err = snd_pcm_sw_params(hPCM, pSWParms);
    430480    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set new software parameters: %s\n", snd_strerror(err)), err);
    431481
     
    444494 *
    445495 * @returns 0 on success, negative errno on failure.
    446  * @param   phPCM   ALSA stream to set software parameters for.
     496 * @param   hPCM   ALSA stream to set software parameters for.
    447497 * @param   pCfgReq Requested configuration to set.
    448498 * @param   pCfgObt Obtained configuration on success. Might differ from
    449499 *                  requested configuration.
    450500 */
    451 static int alsaStreamSetHwParams(snd_pcm_t *phPCM, PALSAAUDIOSTREAMCFG pCfgReq, PALSAAUDIOSTREAMCFG pCfgObt)
     501static int alsaStreamSetHwParams(snd_pcm_t *hPCM, PALSAAUDIOSTREAMCFG pCfgReq, PALSAAUDIOSTREAMCFG pCfgObt)
    452502{
    453503    /*
     
    458508    AssertReturn(pHWParms, -ENOMEM);
    459509
    460     int err = snd_pcm_hw_params_any(phPCM, pHWParms);
     510    int err = snd_pcm_hw_params_any(hPCM, pHWParms);
    461511    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to initialize hardware parameters: %s\n", snd_strerror(err)), err);
    462512
     
    466516     */
    467517    /* We'll use snd_pcm_writei/snd_pcm_readi: */
    468     err = snd_pcm_hw_params_set_access(phPCM, pHWParms, SND_PCM_ACCESS_RW_INTERLEAVED);
     518    err = snd_pcm_hw_params_set_access(hPCM, pHWParms, SND_PCM_ACCESS_RW_INTERLEAVED);
    469519    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set access type: %s\n", snd_strerror(err)), err);
    470520
    471521    /* Set the format, frequency and channel count. */
    472     err = snd_pcm_hw_params_set_format(phPCM, pHWParms, pCfgReq->fmt);
     522    err = snd_pcm_hw_params_set_format(hPCM, pHWParms, pCfgReq->fmt);
    473523    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set audio format to %d: %s\n", pCfgReq->fmt, snd_strerror(err)), err);
    474524
    475525    unsigned int uFreq = pCfgReq->freq;
    476     err = snd_pcm_hw_params_set_rate_near(phPCM, pHWParms, &uFreq, NULL /*dir*/);
     526    err = snd_pcm_hw_params_set_rate_near(hPCM, pHWParms, &uFreq, NULL /*dir*/);
    477527    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set frequency to %uHz: %s\n", pCfgReq->freq, snd_strerror(err)), err);
    478528    pCfgObt->freq      = uFreq;
    479529
    480530    unsigned int cChannels = pCfgReq->nchannels;
    481     err = snd_pcm_hw_params_set_channels_near(phPCM, pHWParms, &cChannels);
     531    err = snd_pcm_hw_params_set_channels_near(hPCM, pHWParms, &cChannels);
    482532    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set number of channels to %d\n", pCfgReq->nchannels), err);
    483533    AssertLogRelMsgReturn(cChannels == 1 || cChannels == 2, ("ALSA: Number of audio channels (%u) not supported\n", cChannels), -1);
     
    493543    if (period_size_f < minval)
    494544        period_size_f = minval;
    495     err = snd_pcm_hw_params_set_period_size_near(phPCM, pHWParms, &period_size_f, 0);
     545    err = snd_pcm_hw_params_set_period_size_near(hPCM, pHWParms, &period_size_f, 0);
    496546    LogRel2(("ALSA: Period size is: %lu frames (min %lu, requested %lu)\n", period_size_f, minval, pCfgReq->period_size));
    497547    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set period size %d (%s)\n", period_size_f, snd_strerror(err)), err);
     
    505555    if (buffer_size_f < minval)
    506556        buffer_size_f = minval;
    507     err = snd_pcm_hw_params_set_buffer_size_near(phPCM, pHWParms, &buffer_size_f);
     557    err = snd_pcm_hw_params_set_buffer_size_near(hPCM, pHWParms, &buffer_size_f);
    508558    LogRel2(("ALSA: Buffer size is: %lu frames (min %lu, requested %lu)\n", buffer_size_f, minval, pCfgReq->buffer_size));
    509559    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set near buffer size %RU32: %s\n", buffer_size_f, snd_strerror(err)), err);
     
    512562     * Set the hardware parameters.
    513563     */
    514     err = snd_pcm_hw_params(phPCM, pHWParms);
     564    err = snd_pcm_hw_params(hPCM, pHWParms);
    515565    AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to apply audio parameters: %s\n", snd_strerror(err)), err);
    516566
     
    558608     */
    559609    int rc = VERR_AUDIO_STREAM_COULD_NOT_CREATE;
    560     snd_pcm_t *phPCM = NULL;
     610    snd_pcm_t *hPCM = NULL;
    561611    LogRel(("ALSA: Using %s device \"%s\"\n", fIn ? "input" : "output", pszDev));
    562     int err = snd_pcm_open(&phPCM, pszDev,
     612    int err = snd_pcm_open(&hPCM, pszDev,
    563613                           fIn ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
    564614                           SND_PCM_NONBLOCK);
    565615    if (err >= 0)
    566616    {
    567         err = snd_pcm_nonblock(phPCM, 1);
     617        err = snd_pcm_nonblock(hPCM, 1);
    568618        if (err >= 0)
    569619        {
     
    571621             * Configure hardware stream parameters.
    572622             */
    573             err = alsaStreamSetHwParams(phPCM, pCfgReq, pCfgObt);
     623            err = alsaStreamSetHwParams(hPCM, pCfgReq, pCfgObt);
    574624            if (err >= 0)
    575625            {
     
    578628                 */
    579629                rc = VERR_AUDIO_BACKEND_INIT_FAILED;
    580                 err = snd_pcm_prepare(phPCM);
     630                err = snd_pcm_prepare(hPCM);
    581631                if (err >= 0)
    582632                {
     
    584634                     * Configure software stream parameters and we're done.
    585635                     */
    586                     rc = alsaStreamSetSWParams(phPCM, fIn, pCfgReq, pCfgObt);
     636                    rc = alsaStreamSetSWParams(hPCM, fIn, pCfgReq, pCfgObt);
    587637                    if (RT_SUCCESS(rc))
    588638                    {
    589                         *pphPCM = phPCM;
     639                        *pphPCM = hPCM;
    590640                        return VINF_SUCCESS;
    591641                    }
     
    597647        else
    598648            LogRel(("ALSA: Error setting output non-blocking mode: %s\n", snd_strerror(err)));
    599         alsaStreamClose(&phPCM);
     649        alsaStreamClose(&hPCM);
    600650    }
    601651    else
     
    618668                               PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    619669{
    620     snd_pcm_t *phPCM = NULL;
     670    snd_pcm_t *hPCM = NULL;
    621671
    622672    int rc;
     
    633683
    634684        ALSAAUDIOSTREAMCFG obt;
    635         rc = alsaStreamOpen(pThis->szDefaultOut, false /* fIn */, &req, &obt, &phPCM);
     685        rc = alsaStreamOpen(pThis->szDefaultOut, false /* fIn */, &req, &obt, &hPCM);
    636686        if (RT_FAILURE(rc))
    637687            break;
     
    645695        pCfgAcq->Backend.cFramesPreBuffering     = obt.threshold;
    646696
    647         pStreamALSA->phPCM = phPCM;
     697        pStreamALSA->hPCM = hPCM;
    648698    }
    649699    while (0);
    650700
    651701    if (RT_FAILURE(rc))
    652         alsaStreamClose(&phPCM);
     702        alsaStreamClose(&hPCM);
    653703
    654704    LogFlowFuncLeaveRC(rc);
     
    672722    int rc;
    673723
    674     snd_pcm_t *phPCM = NULL;
     724    snd_pcm_t *hPCM = NULL;
    675725
    676726    do
     
    685735
    686736        ALSAAUDIOSTREAMCFG obt;
    687         rc = alsaStreamOpen(pThis->szDefaultIn, true /* fIn */, &req, &obt, &phPCM);
     737        rc = alsaStreamOpen(pThis->szDefaultIn, true /* fIn */, &req, &obt, &hPCM);
    688738        if (RT_FAILURE(rc))
    689739            break;
     
    697747        pCfgAcq->Backend.cFramesPreBuffering = 0; /* No pre-buffering. */
    698748
    699         pStreamALSA->phPCM = phPCM;
     749        pStreamALSA->hPCM = hPCM;
    700750    }
    701751    while (0);
    702752
    703753    if (RT_FAILURE(rc))
    704         alsaStreamClose(&phPCM);
     754        alsaStreamClose(&hPCM);
    705755
    706756    LogFlowFuncLeaveRC(rc);
     
    752802        return VINF_SUCCESS;
    753803
    754     int rc = alsaStreamClose(&pStreamALSA->phPCM);
     804    int rc = alsaStreamClose(&pStreamALSA->hPCM);
    755805    /** @todo r=bird: It's not like we can do much with a bad status... Check
    756806     *        what the caller does... */
     
    783833        case PDMAUDIOSTREAMCMD_RESUME:
    784834        {
    785             err = snd_pcm_prepare(pStreamALSA->phPCM);
     835            err = snd_pcm_prepare(pStreamALSA->hPCM);
    786836            if (err < 0)
    787837            {
     
    791841            else
    792842            {
    793                 Assert(snd_pcm_state(pStreamALSA->phPCM) == SND_PCM_STATE_PREPARED);
     843                Assert(snd_pcm_state(pStreamALSA->hPCM) == SND_PCM_STATE_PREPARED);
    794844
    795845                /* Only start the PCM stream for input streams. */
    796                 err = snd_pcm_start(pStreamALSA->phPCM);
     846                err = snd_pcm_start(pStreamALSA->hPCM);
    797847                if (err < 0)
    798848                {
     
    807857        case PDMAUDIOSTREAMCMD_DISABLE:
    808858        {
    809             err = snd_pcm_drop(pStreamALSA->phPCM);
     859            err = snd_pcm_drop(pStreamALSA->hPCM);
    810860            if (err < 0)
    811861            {
     
    818868        case PDMAUDIOSTREAMCMD_PAUSE:
    819869        {
    820             err = snd_pcm_drop(pStreamALSA->phPCM);
     870            err = snd_pcm_drop(pStreamALSA->hPCM);
    821871            if (err < 0)
    822872            {
     
    855905        case PDMAUDIOSTREAMCMD_RESUME:
    856906        {
    857             err = snd_pcm_prepare(pStreamALSA->phPCM);
     907            err = snd_pcm_prepare(pStreamALSA->hPCM);
    858908            if (err < 0)
    859909            {
     
    863913            else
    864914            {
    865                 Assert(snd_pcm_state(pStreamALSA->phPCM) == SND_PCM_STATE_PREPARED);
     915                Assert(snd_pcm_state(pStreamALSA->hPCM) == SND_PCM_STATE_PREPARED);
    866916            }
    867917
     
    871921        case PDMAUDIOSTREAMCMD_DISABLE:
    872922        {
    873             err = snd_pcm_drop(pStreamALSA->phPCM);
     923            err = snd_pcm_drop(pStreamALSA->hPCM);
    874924            if (err < 0)
    875925            {
     
    883933        {
    884934            /** @todo shouldn't this try snd_pcm_pause first? */
    885             err = snd_pcm_drop(pStreamALSA->phPCM);
     935            err = snd_pcm_drop(pStreamALSA->hPCM);
    886936            if (err < 0)
    887937            {
     
    894944        case PDMAUDIOSTREAMCMD_DRAIN:
    895945        {
    896             snd_pcm_state_t streamState = snd_pcm_state(pStreamALSA->phPCM);
     946            snd_pcm_state_t streamState = snd_pcm_state(pStreamALSA->hPCM);
    897947            Log2Func(("Stream state is: %d\n", streamState));
    898948
     
    902952                /** @todo r=bird: You want EMT to block here for potentially 200-300ms worth
    903953                 *        of buffer to be drained?  That's a certifiably bad idea.  */
    904                 err = snd_pcm_nonblock(pStreamALSA->phPCM, 0);
     954                err = snd_pcm_nonblock(pStreamALSA->hPCM, 0);
    905955                if (err < 0)
    906956                {
     
    910960                }
    911961
    912                 err = snd_pcm_drain(pStreamALSA->phPCM);
     962                err = snd_pcm_drain(pStreamALSA->hPCM);
    913963                if (err < 0)
    914964                {
     
    918968                }
    919969
    920                 err = snd_pcm_nonblock(pStreamALSA->phPCM, 1);
     970                err = snd_pcm_nonblock(pStreamALSA->hPCM, 1);
    921971                if (err < 0)
    922972                {
     
    9661016 *
    9671017 * @returns VBox status code.
    968  * @param   phPCM           ALSA stream handle.
     1018 * @param   hPCM           ALSA stream handle.
    9691019 * @param   pcFramesAvail   Where to store the available frames.
    9701020 */
    971 static int alsaStreamGetAvail(snd_pcm_t *phPCM, snd_pcm_sframes_t *pcFramesAvail)
    972 {
    973     AssertPtr(phPCM);
     1021static int alsaStreamGetAvail(snd_pcm_t *hPCM, snd_pcm_sframes_t *pcFramesAvail)
     1022{
     1023    AssertPtr(hPCM);
    9741024    AssertPtr(pcFramesAvail);
    9751025
    9761026    int rc;
    977     snd_pcm_sframes_t cFramesAvail = snd_pcm_avail_update(phPCM);
     1027    snd_pcm_sframes_t cFramesAvail = snd_pcm_avail_update(hPCM);
    9781028    if (cFramesAvail > 0)
    9791029    {
     
    9851035    if (cFramesAvail == -EPIPE)
    9861036    {
    987         rc = alsaStreamRecover(phPCM);
     1037        rc = alsaStreamRecover(hPCM);
    9881038        if (RT_SUCCESS(rc))
    9891039        {
    990             cFramesAvail = snd_pcm_avail_update(phPCM);
     1040            cFramesAvail = snd_pcm_avail_update(hPCM);
    9911041            if (cFramesAvail >= 0)
    9921042            {
     
    10221072
    10231073    snd_pcm_sframes_t cFramesAvail;
    1024     int rc = alsaStreamGetAvail(pStreamALSA->phPCM, &cFramesAvail);
     1074    int rc = alsaStreamGetAvail(pStreamALSA->hPCM, &cFramesAvail);
    10251075    if (RT_SUCCESS(rc))
    10261076        cbAvail = PDMAUDIOSTREAMCFG_F2B(pStreamALSA->pCfg, cFramesAvail);
     
    10421092
    10431093    snd_pcm_sframes_t cFramesAvail;
    1044     int rc = alsaStreamGetAvail(pStreamALSA->phPCM, &cFramesAvail);
     1094    int rc = alsaStreamGetAvail(pStreamALSA->hPCM, &cFramesAvail);
    10451095    if (RT_SUCCESS(rc))
    10461096        cbAvail = PDMAUDIOSTREAMCFG_F2B(pStreamALSA->pCfg, cFramesAvail);
     
    10781128        snd_pcm_sframes_t cFramesAvail = 0;
    10791129        snd_pcm_sframes_t cFramesDelay = 0;
    1080         int rc = snd_pcm_avail_delay(pStreamALSA->phPCM, &cFramesAvail, &cFramesDelay);
     1130        int rc = snd_pcm_avail_delay(pStreamALSA->hPCM, &cFramesAvail, &cFramesDelay);
    10811131
    10821132        /*
     
    10841134         * we're not in a playing state.
    10851135         */
    1086         snd_pcm_state_t enmState = snd_pcm_state(pStreamALSA->phPCM);
     1136        snd_pcm_state_t enmState = snd_pcm_state(pStreamALSA->hPCM);
    10871137        switch (enmState)
    10881138        {
     
    11401190     */
    11411191    snd_pcm_sframes_t cAvail;
    1142     int rc = alsaStreamGetAvail(pStreamALSA->phPCM, &cAvail);
     1192    int rc = alsaStreamGetAvail(pStreamALSA->hPCM, &cAvail);
    11431193    if (RT_SUCCESS(rc))
    11441194    {
    11451195        if (!cAvail) /* No data yet? */
    11461196        {
    1147             snd_pcm_state_t enmState = snd_pcm_state(pStreamALSA->phPCM);
     1197            snd_pcm_state_t enmState = snd_pcm_state(pStreamALSA->hPCM);
    11481198            switch (enmState)
    11491199            {
     
    11541204
    11551205                case SND_PCM_STATE_SUSPENDED:
    1156                     rc = alsaStreamResume(pStreamALSA->phPCM);
     1206                    rc = alsaStreamResume(pStreamALSA->hPCM);
    11571207                    if (RT_SUCCESS(rc))
    11581208                    {
     
    11961246        AssertBreakStmt(cFramesToRead > 0, rc = VERR_NO_DATA);
    11971247
    1198         snd_pcm_sframes_t cFramesRead = snd_pcm_readi(pStreamALSA->phPCM, pvBuf, cFramesToRead);
     1248        snd_pcm_sframes_t cFramesRead = snd_pcm_readi(pStreamALSA->hPCM, pvBuf, cFramesToRead);
    11991249        if (cFramesRead > 0)
    12001250        {
     
    12191269            if (cFramesRead == -EPIPE)
    12201270            {
    1221                 rc = alsaStreamRecover(pStreamALSA->phPCM);
     1271                rc = alsaStreamRecover(pStreamALSA->hPCM);
    12221272                if (RT_SUCCESS(rc))
    12231273                {
     
    12661316    AssertPtrReturn(pcbWritten, VERR_INVALID_POINTER);
    12671317    Log4Func(("@%#RX64: pvBuf=%p cbBuf=%#x (%u) state=%s - %s\n", pStreamALSA->offInternal, pvBuf, cbBuf, cbBuf,
    1268               snd_pcm_state_name(snd_pcm_state(pStreamALSA->phPCM)), pStreamALSA->pCfg->szName));
     1318              snd_pcm_state_name(snd_pcm_state(pStreamALSA->hPCM)), pStreamALSA->pCfg->szName));
    12691319
    12701320    /*
     
    12731323     */
    12741324    snd_pcm_sframes_t cFramesAvail;
    1275     int rc = alsaStreamGetAvail(pStreamALSA->phPCM, &cFramesAvail);
     1325    int rc = alsaStreamGetAvail(pStreamALSA->hPCM, &cFramesAvail);
    12761326    if (RT_SUCCESS(rc))
    12771327    {
     
    12901340                 */
    12911341                uint32_t cFramesToWrite = PDMAudioPropsBytesToFrames(pProps, cbToWrite);
    1292                 snd_pcm_sframes_t cFramesWritten = snd_pcm_writei(pStreamALSA->phPCM, pvBuf, cFramesToWrite);
     1342                snd_pcm_sframes_t cFramesWritten = snd_pcm_writei(pStreamALSA->hPCM, pvBuf, cFramesToWrite);
    12931343                if (cFramesWritten > 0)
    12941344                {
     
    13131363                    {
    13141364                        /* Underrun occurred. */
    1315                         rc = alsaStreamRecover(pStreamALSA->phPCM);
     1365                        rc = alsaStreamRecover(pStreamALSA->hPCM);
    13161366                        if (RT_FAILURE(rc))
    13171367                            break;
     
    13211371                    {
    13221372                        /* An suspended event occurred, needs resuming. */
    1323                         rc = alsaStreamResume(pStreamALSA->phPCM);
     1373                        rc = alsaStreamResume(pStreamALSA->hPCM);
    13241374                        if (RT_FAILURE(rc))
    13251375                        {
     
    13301380                    }
    13311381
    1332                     cFramesWritten = snd_pcm_writei(pStreamALSA->phPCM, pvBuf, cFramesToWrite);
     1382                    cFramesWritten = snd_pcm_writei(pStreamALSA->hPCM, pvBuf, cFramesToWrite);
    13331383                    if (cFramesWritten > 0)
    13341384                    {
     
    13971447    /* IHostAudio */
    13981448    pThis->IHostAudio.pfnGetConfig          = drvHostAlsaAudioHA_GetConfig;
    1399     pThis->IHostAudio.pfnGetDevices         = NULL;
     1449    pThis->IHostAudio.pfnGetDevices         = drvHostAlsaAudioHA_GetDevices;
    14001450    pThis->IHostAudio.pfnGetStatus          = drvHostAlsaAudioHA_GetStatus;
    14011451    pThis->IHostAudio.pfnStreamCreate       = drvHostAlsaAudioHA_StreamCreate;
Note: See TracChangeset for help on using the changeset viewer.

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