Changeset 88451 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Apr 9, 2021 10:34:33 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 143703
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp
r88450 r88451 51 51 #include <VBox/vmm/pdmaudioifs.h> 52 52 #include <VBox/vmm/pdmaudioinline.h> 53 #include <VBox/vmm/pdmaudiohostenuminline.h> 53 54 54 55 RT_C_DECLS_BEGIN … … 64 65 65 66 /********************************************************************************************************************************* 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 /********************************************************************************************************************************* 66 74 * Structures * 67 75 *********************************************************************************************************************************/ 68 /**69 * Structure for maintaining an ALSA audio stream.70 */71 typedef struct ALSAAUDIOSTREAM72 {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 PDMIAUDIOCONNECTOR88 */89 typedef struct DRVHOSTALSAAUDIO90 {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 5106 107 76 /** 108 77 * Structure for maintaining an ALSA audio stream configuration. … … 123 92 /** Periods (in audio frames). */ 124 93 unsigned long period_size; 125 /** For playback: Starting to play threshold (in audio frames).94 /** For playback: Starting to play threshold (in audio frames). 126 95 * For Capturing: Starting to capture threshold (in audio frames). */ 127 96 unsigned long threshold; 97 98 /* latency = period_size * periods / (rate * bytes_per_frame) */ 128 99 } ALSAAUDIOSTREAMCFG, *PALSAAUDIOSTREAMCFG; 100 101 /** 102 * Structure for maintaining an ALSA audio stream. 103 */ 104 typedef 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 */ 119 typedef 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; 129 133 130 134 … … 173 177 * 174 178 * @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 */ 181 static int alsaStreamRecover(snd_pcm_t *hPCM) 182 { 183 AssertPtrReturn(hPCM, VERR_INVALID_POINTER); 184 185 int err = snd_pcm_prepare(hPCM); 182 186 if (err < 0) 183 187 { 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))); 185 189 return VERR_ACCESS_DENIED; /** @todo Find a better rc. */ 186 190 } … … 193 197 * 194 198 * @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 */ 201 static int alsaStreamResume(snd_pcm_t *hPCM) 202 { 203 AssertPtrReturn(hPCM, VERR_INVALID_POINTER); 204 205 int err = snd_pcm_resume(hPCM); 202 206 if (err < 0) 203 207 { 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))); 205 209 return VERR_ACCESS_DENIED; /** @todo Find a better rc. */ 206 210 } … … 218 222 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 219 223 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"); 222 228 pBackendCfg->cbStreamIn = sizeof(ALSAAUDIOSTREAM); 223 229 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 = !pszDev235 || !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 0248 if (!RTStrICmp("input", pszIOID))249 250 else if (!RTStrICmp("output", pszIOID))251 #endif252 }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 ( pszDev261 && 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 else277 LogRel2(("ALSA: Error enumerating PCM devices: %Rrc (%d)\n", RTErrConvertFromErrno(err), err));278 230 279 231 /* ALSA allows exactly one input and one output used at a time for the selected device(s). */ … … 284 236 } 285 237 238 239 /** 240 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetDevices} 241 */ 242 static 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 } 286 336 287 337 /** … … 393 443 * 394 444 * @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. 396 446 * @param fIn Whether this is an input stream or not. 397 447 * @param pCfgReq Requested configuration to set. 398 448 * @param pCfgObt Obtained configuration on success. Might differ from requested configuration. 399 449 */ 400 static int alsaStreamSetSWParams(snd_pcm_t * phPCM, bool fIn, PALSAAUDIOSTREAMCFG pCfgReq, PALSAAUDIOSTREAMCFG pCfgObt)450 static int alsaStreamSetSWParams(snd_pcm_t *hPCM, bool fIn, PALSAAUDIOSTREAMCFG pCfgReq, PALSAAUDIOSTREAMCFG pCfgObt) 401 451 { 402 452 if (fIn) /* For input streams there's nothing to do in here right now. */ … … 407 457 AssertReturn(pSWParms, -ENOMEM); 408 458 409 int err = snd_pcm_sw_params_current( phPCM, pSWParms);459 int err = snd_pcm_sw_params_current(hPCM, pSWParms); 410 460 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to get current software parameters: %s\n", snd_strerror(err)), err); 411 461 … … 420 470 pCfgReq->threshold, cFramesPreBuffer, pCfgObt->buffer_size)); 421 471 } 422 err = snd_pcm_sw_params_set_start_threshold( phPCM, pSWParms, cFramesPreBuffer);472 err = snd_pcm_sw_params_set_start_threshold(hPCM, pSWParms, cFramesPreBuffer); 423 473 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set software threshold to %lu: %s\n", cFramesPreBuffer, snd_strerror(err)), err); 424 474 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); 426 476 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set available minimum to %lu: %s\n", pCfgReq->period_size, snd_strerror(err)), err); 427 477 428 478 /* Commit the software parameters: */ 429 err = snd_pcm_sw_params( phPCM, pSWParms);479 err = snd_pcm_sw_params(hPCM, pSWParms); 430 480 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set new software parameters: %s\n", snd_strerror(err)), err); 431 481 … … 444 494 * 445 495 * @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. 447 497 * @param pCfgReq Requested configuration to set. 448 498 * @param pCfgObt Obtained configuration on success. Might differ from 449 499 * requested configuration. 450 500 */ 451 static int alsaStreamSetHwParams(snd_pcm_t * phPCM, PALSAAUDIOSTREAMCFG pCfgReq, PALSAAUDIOSTREAMCFG pCfgObt)501 static int alsaStreamSetHwParams(snd_pcm_t *hPCM, PALSAAUDIOSTREAMCFG pCfgReq, PALSAAUDIOSTREAMCFG pCfgObt) 452 502 { 453 503 /* … … 458 508 AssertReturn(pHWParms, -ENOMEM); 459 509 460 int err = snd_pcm_hw_params_any( phPCM, pHWParms);510 int err = snd_pcm_hw_params_any(hPCM, pHWParms); 461 511 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to initialize hardware parameters: %s\n", snd_strerror(err)), err); 462 512 … … 466 516 */ 467 517 /* 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); 469 519 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set access type: %s\n", snd_strerror(err)), err); 470 520 471 521 /* 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); 473 523 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set audio format to %d: %s\n", pCfgReq->fmt, snd_strerror(err)), err); 474 524 475 525 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*/); 477 527 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set frequency to %uHz: %s\n", pCfgReq->freq, snd_strerror(err)), err); 478 528 pCfgObt->freq = uFreq; 479 529 480 530 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); 482 532 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set number of channels to %d\n", pCfgReq->nchannels), err); 483 533 AssertLogRelMsgReturn(cChannels == 1 || cChannels == 2, ("ALSA: Number of audio channels (%u) not supported\n", cChannels), -1); … … 493 543 if (period_size_f < minval) 494 544 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); 496 546 LogRel2(("ALSA: Period size is: %lu frames (min %lu, requested %lu)\n", period_size_f, minval, pCfgReq->period_size)); 497 547 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set period size %d (%s)\n", period_size_f, snd_strerror(err)), err); … … 505 555 if (buffer_size_f < minval) 506 556 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); 508 558 LogRel2(("ALSA: Buffer size is: %lu frames (min %lu, requested %lu)\n", buffer_size_f, minval, pCfgReq->buffer_size)); 509 559 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to set near buffer size %RU32: %s\n", buffer_size_f, snd_strerror(err)), err); … … 512 562 * Set the hardware parameters. 513 563 */ 514 err = snd_pcm_hw_params( phPCM, pHWParms);564 err = snd_pcm_hw_params(hPCM, pHWParms); 515 565 AssertLogRelMsgReturn(err >= 0, ("ALSA: Failed to apply audio parameters: %s\n", snd_strerror(err)), err); 516 566 … … 558 608 */ 559 609 int rc = VERR_AUDIO_STREAM_COULD_NOT_CREATE; 560 snd_pcm_t * phPCM = NULL;610 snd_pcm_t *hPCM = NULL; 561 611 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, 563 613 fIn ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, 564 614 SND_PCM_NONBLOCK); 565 615 if (err >= 0) 566 616 { 567 err = snd_pcm_nonblock( phPCM, 1);617 err = snd_pcm_nonblock(hPCM, 1); 568 618 if (err >= 0) 569 619 { … … 571 621 * Configure hardware stream parameters. 572 622 */ 573 err = alsaStreamSetHwParams( phPCM, pCfgReq, pCfgObt);623 err = alsaStreamSetHwParams(hPCM, pCfgReq, pCfgObt); 574 624 if (err >= 0) 575 625 { … … 578 628 */ 579 629 rc = VERR_AUDIO_BACKEND_INIT_FAILED; 580 err = snd_pcm_prepare( phPCM);630 err = snd_pcm_prepare(hPCM); 581 631 if (err >= 0) 582 632 { … … 584 634 * Configure software stream parameters and we're done. 585 635 */ 586 rc = alsaStreamSetSWParams( phPCM, fIn, pCfgReq, pCfgObt);636 rc = alsaStreamSetSWParams(hPCM, fIn, pCfgReq, pCfgObt); 587 637 if (RT_SUCCESS(rc)) 588 638 { 589 *pphPCM = phPCM;639 *pphPCM = hPCM; 590 640 return VINF_SUCCESS; 591 641 } … … 597 647 else 598 648 LogRel(("ALSA: Error setting output non-blocking mode: %s\n", snd_strerror(err))); 599 alsaStreamClose(& phPCM);649 alsaStreamClose(&hPCM); 600 650 } 601 651 else … … 618 668 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 619 669 { 620 snd_pcm_t * phPCM = NULL;670 snd_pcm_t *hPCM = NULL; 621 671 622 672 int rc; … … 633 683 634 684 ALSAAUDIOSTREAMCFG obt; 635 rc = alsaStreamOpen(pThis->szDefaultOut, false /* fIn */, &req, &obt, & phPCM);685 rc = alsaStreamOpen(pThis->szDefaultOut, false /* fIn */, &req, &obt, &hPCM); 636 686 if (RT_FAILURE(rc)) 637 687 break; … … 645 695 pCfgAcq->Backend.cFramesPreBuffering = obt.threshold; 646 696 647 pStreamALSA-> phPCM = phPCM;697 pStreamALSA->hPCM = hPCM; 648 698 } 649 699 while (0); 650 700 651 701 if (RT_FAILURE(rc)) 652 alsaStreamClose(& phPCM);702 alsaStreamClose(&hPCM); 653 703 654 704 LogFlowFuncLeaveRC(rc); … … 672 722 int rc; 673 723 674 snd_pcm_t * phPCM = NULL;724 snd_pcm_t *hPCM = NULL; 675 725 676 726 do … … 685 735 686 736 ALSAAUDIOSTREAMCFG obt; 687 rc = alsaStreamOpen(pThis->szDefaultIn, true /* fIn */, &req, &obt, & phPCM);737 rc = alsaStreamOpen(pThis->szDefaultIn, true /* fIn */, &req, &obt, &hPCM); 688 738 if (RT_FAILURE(rc)) 689 739 break; … … 697 747 pCfgAcq->Backend.cFramesPreBuffering = 0; /* No pre-buffering. */ 698 748 699 pStreamALSA-> phPCM = phPCM;749 pStreamALSA->hPCM = hPCM; 700 750 } 701 751 while (0); 702 752 703 753 if (RT_FAILURE(rc)) 704 alsaStreamClose(& phPCM);754 alsaStreamClose(&hPCM); 705 755 706 756 LogFlowFuncLeaveRC(rc); … … 752 802 return VINF_SUCCESS; 753 803 754 int rc = alsaStreamClose(&pStreamALSA-> phPCM);804 int rc = alsaStreamClose(&pStreamALSA->hPCM); 755 805 /** @todo r=bird: It's not like we can do much with a bad status... Check 756 806 * what the caller does... */ … … 783 833 case PDMAUDIOSTREAMCMD_RESUME: 784 834 { 785 err = snd_pcm_prepare(pStreamALSA-> phPCM);835 err = snd_pcm_prepare(pStreamALSA->hPCM); 786 836 if (err < 0) 787 837 { … … 791 841 else 792 842 { 793 Assert(snd_pcm_state(pStreamALSA-> phPCM) == SND_PCM_STATE_PREPARED);843 Assert(snd_pcm_state(pStreamALSA->hPCM) == SND_PCM_STATE_PREPARED); 794 844 795 845 /* Only start the PCM stream for input streams. */ 796 err = snd_pcm_start(pStreamALSA-> phPCM);846 err = snd_pcm_start(pStreamALSA->hPCM); 797 847 if (err < 0) 798 848 { … … 807 857 case PDMAUDIOSTREAMCMD_DISABLE: 808 858 { 809 err = snd_pcm_drop(pStreamALSA-> phPCM);859 err = snd_pcm_drop(pStreamALSA->hPCM); 810 860 if (err < 0) 811 861 { … … 818 868 case PDMAUDIOSTREAMCMD_PAUSE: 819 869 { 820 err = snd_pcm_drop(pStreamALSA-> phPCM);870 err = snd_pcm_drop(pStreamALSA->hPCM); 821 871 if (err < 0) 822 872 { … … 855 905 case PDMAUDIOSTREAMCMD_RESUME: 856 906 { 857 err = snd_pcm_prepare(pStreamALSA-> phPCM);907 err = snd_pcm_prepare(pStreamALSA->hPCM); 858 908 if (err < 0) 859 909 { … … 863 913 else 864 914 { 865 Assert(snd_pcm_state(pStreamALSA-> phPCM) == SND_PCM_STATE_PREPARED);915 Assert(snd_pcm_state(pStreamALSA->hPCM) == SND_PCM_STATE_PREPARED); 866 916 } 867 917 … … 871 921 case PDMAUDIOSTREAMCMD_DISABLE: 872 922 { 873 err = snd_pcm_drop(pStreamALSA-> phPCM);923 err = snd_pcm_drop(pStreamALSA->hPCM); 874 924 if (err < 0) 875 925 { … … 883 933 { 884 934 /** @todo shouldn't this try snd_pcm_pause first? */ 885 err = snd_pcm_drop(pStreamALSA-> phPCM);935 err = snd_pcm_drop(pStreamALSA->hPCM); 886 936 if (err < 0) 887 937 { … … 894 944 case PDMAUDIOSTREAMCMD_DRAIN: 895 945 { 896 snd_pcm_state_t streamState = snd_pcm_state(pStreamALSA-> phPCM);946 snd_pcm_state_t streamState = snd_pcm_state(pStreamALSA->hPCM); 897 947 Log2Func(("Stream state is: %d\n", streamState)); 898 948 … … 902 952 /** @todo r=bird: You want EMT to block here for potentially 200-300ms worth 903 953 * 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); 905 955 if (err < 0) 906 956 { … … 910 960 } 911 961 912 err = snd_pcm_drain(pStreamALSA-> phPCM);962 err = snd_pcm_drain(pStreamALSA->hPCM); 913 963 if (err < 0) 914 964 { … … 918 968 } 919 969 920 err = snd_pcm_nonblock(pStreamALSA-> phPCM, 1);970 err = snd_pcm_nonblock(pStreamALSA->hPCM, 1); 921 971 if (err < 0) 922 972 { … … 966 1016 * 967 1017 * @returns VBox status code. 968 * @param phPCM ALSA stream handle.1018 * @param hPCM ALSA stream handle. 969 1019 * @param pcFramesAvail Where to store the available frames. 970 1020 */ 971 static int alsaStreamGetAvail(snd_pcm_t * phPCM, snd_pcm_sframes_t *pcFramesAvail)972 { 973 AssertPtr( phPCM);1021 static int alsaStreamGetAvail(snd_pcm_t *hPCM, snd_pcm_sframes_t *pcFramesAvail) 1022 { 1023 AssertPtr(hPCM); 974 1024 AssertPtr(pcFramesAvail); 975 1025 976 1026 int rc; 977 snd_pcm_sframes_t cFramesAvail = snd_pcm_avail_update( phPCM);1027 snd_pcm_sframes_t cFramesAvail = snd_pcm_avail_update(hPCM); 978 1028 if (cFramesAvail > 0) 979 1029 { … … 985 1035 if (cFramesAvail == -EPIPE) 986 1036 { 987 rc = alsaStreamRecover( phPCM);1037 rc = alsaStreamRecover(hPCM); 988 1038 if (RT_SUCCESS(rc)) 989 1039 { 990 cFramesAvail = snd_pcm_avail_update( phPCM);1040 cFramesAvail = snd_pcm_avail_update(hPCM); 991 1041 if (cFramesAvail >= 0) 992 1042 { … … 1022 1072 1023 1073 snd_pcm_sframes_t cFramesAvail; 1024 int rc = alsaStreamGetAvail(pStreamALSA-> phPCM, &cFramesAvail);1074 int rc = alsaStreamGetAvail(pStreamALSA->hPCM, &cFramesAvail); 1025 1075 if (RT_SUCCESS(rc)) 1026 1076 cbAvail = PDMAUDIOSTREAMCFG_F2B(pStreamALSA->pCfg, cFramesAvail); … … 1042 1092 1043 1093 snd_pcm_sframes_t cFramesAvail; 1044 int rc = alsaStreamGetAvail(pStreamALSA-> phPCM, &cFramesAvail);1094 int rc = alsaStreamGetAvail(pStreamALSA->hPCM, &cFramesAvail); 1045 1095 if (RT_SUCCESS(rc)) 1046 1096 cbAvail = PDMAUDIOSTREAMCFG_F2B(pStreamALSA->pCfg, cFramesAvail); … … 1078 1128 snd_pcm_sframes_t cFramesAvail = 0; 1079 1129 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); 1081 1131 1082 1132 /* … … 1084 1134 * we're not in a playing state. 1085 1135 */ 1086 snd_pcm_state_t enmState = snd_pcm_state(pStreamALSA-> phPCM);1136 snd_pcm_state_t enmState = snd_pcm_state(pStreamALSA->hPCM); 1087 1137 switch (enmState) 1088 1138 { … … 1140 1190 */ 1141 1191 snd_pcm_sframes_t cAvail; 1142 int rc = alsaStreamGetAvail(pStreamALSA-> phPCM, &cAvail);1192 int rc = alsaStreamGetAvail(pStreamALSA->hPCM, &cAvail); 1143 1193 if (RT_SUCCESS(rc)) 1144 1194 { 1145 1195 if (!cAvail) /* No data yet? */ 1146 1196 { 1147 snd_pcm_state_t enmState = snd_pcm_state(pStreamALSA-> phPCM);1197 snd_pcm_state_t enmState = snd_pcm_state(pStreamALSA->hPCM); 1148 1198 switch (enmState) 1149 1199 { … … 1154 1204 1155 1205 case SND_PCM_STATE_SUSPENDED: 1156 rc = alsaStreamResume(pStreamALSA-> phPCM);1206 rc = alsaStreamResume(pStreamALSA->hPCM); 1157 1207 if (RT_SUCCESS(rc)) 1158 1208 { … … 1196 1246 AssertBreakStmt(cFramesToRead > 0, rc = VERR_NO_DATA); 1197 1247 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); 1199 1249 if (cFramesRead > 0) 1200 1250 { … … 1219 1269 if (cFramesRead == -EPIPE) 1220 1270 { 1221 rc = alsaStreamRecover(pStreamALSA-> phPCM);1271 rc = alsaStreamRecover(pStreamALSA->hPCM); 1222 1272 if (RT_SUCCESS(rc)) 1223 1273 { … … 1266 1316 AssertPtrReturn(pcbWritten, VERR_INVALID_POINTER); 1267 1317 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)); 1269 1319 1270 1320 /* … … 1273 1323 */ 1274 1324 snd_pcm_sframes_t cFramesAvail; 1275 int rc = alsaStreamGetAvail(pStreamALSA-> phPCM, &cFramesAvail);1325 int rc = alsaStreamGetAvail(pStreamALSA->hPCM, &cFramesAvail); 1276 1326 if (RT_SUCCESS(rc)) 1277 1327 { … … 1290 1340 */ 1291 1341 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); 1293 1343 if (cFramesWritten > 0) 1294 1344 { … … 1313 1363 { 1314 1364 /* Underrun occurred. */ 1315 rc = alsaStreamRecover(pStreamALSA-> phPCM);1365 rc = alsaStreamRecover(pStreamALSA->hPCM); 1316 1366 if (RT_FAILURE(rc)) 1317 1367 break; … … 1321 1371 { 1322 1372 /* An suspended event occurred, needs resuming. */ 1323 rc = alsaStreamResume(pStreamALSA-> phPCM);1373 rc = alsaStreamResume(pStreamALSA->hPCM); 1324 1374 if (RT_FAILURE(rc)) 1325 1375 { … … 1330 1380 } 1331 1381 1332 cFramesWritten = snd_pcm_writei(pStreamALSA-> phPCM, pvBuf, cFramesToWrite);1382 cFramesWritten = snd_pcm_writei(pStreamALSA->hPCM, pvBuf, cFramesToWrite); 1333 1383 if (cFramesWritten > 0) 1334 1384 { … … 1397 1447 /* IHostAudio */ 1398 1448 pThis->IHostAudio.pfnGetConfig = drvHostAlsaAudioHA_GetConfig; 1399 pThis->IHostAudio.pfnGetDevices = NULL;1449 pThis->IHostAudio.pfnGetDevices = drvHostAlsaAudioHA_GetDevices; 1400 1450 pThis->IHostAudio.pfnGetStatus = drvHostAlsaAudioHA_GetStatus; 1401 1451 pThis->IHostAudio.pfnStreamCreate = drvHostAlsaAudioHA_StreamCreate;
Note:
See TracChangeset
for help on using the changeset viewer.