Changeset 101458 in vbox for trunk/src/VBox/Main/src-client/ConsoleImplConfigCommon.cpp
- Timestamp:
- Oct 17, 2023 8:09:12 AM (15 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/ConsoleImplConfigCommon.cpp
r101318 r101458 47 47 #include "DisplayImpl.h" 48 48 #include "NvramStoreImpl.h" 49 #include "BusAssignmentManager.h" 49 50 #ifdef VBOX_WITH_DRAG_AND_DROP 50 51 # include "GuestImpl.h" … … 3422 3423 3423 3424 3425 #define H() AssertLogRelMsgReturn(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR) 3426 #define VRC() AssertLogRelMsgReturn(RT_SUCCESS(vrc), ("vrc=%Rrc\n", vrc), vrc) 3427 3428 int Console::i_configAudioCtrl(ComPtr<IVirtualBox> pVBox, ComPtr<IMachine> pMachine, BusAssignmentManager *pBusMgr, PCFGMNODE pDevices, 3429 bool fOsXGuest, bool *pfAudioEnabled) 3430 { 3431 Utf8Str strTmp; 3432 PCFGMNODE pDev = NULL; /* /Devices/Dev/ */ 3433 PCFGMNODE pInst = NULL; /* /Devices/Dev/0/ */ 3434 PCFGMNODE pCfg = NULL; /* /Devices/Dev/.../Config/ */ 3435 PCFGMNODE pLunL0 = NULL; /* /Devices/Dev/0/LUN#0/ */ 3436 3437 /* 3438 * AC'97 ICH / SoundBlaster16 audio / Intel HD Audio. 3439 */ 3440 ComPtr<IAudioSettings> audioSettings; 3441 HRESULT hrc = pMachine->COMGETTER(AudioSettings)(audioSettings.asOutParam()); H(); 3442 3443 BOOL fAudioEnabled = FALSE; 3444 ComPtr<IAudioAdapter> audioAdapter; 3445 hrc = audioSettings->COMGETTER(Adapter)(audioAdapter.asOutParam()); H(); 3446 if (audioAdapter) 3447 { 3448 hrc = audioAdapter->COMGETTER(Enabled)(&fAudioEnabled); H(); 3449 } 3450 3451 if (fAudioEnabled) 3452 { 3453 *pfAudioEnabled = true; 3454 3455 AudioControllerType_T enmAudioController; 3456 hrc = audioAdapter->COMGETTER(AudioController)(&enmAudioController); H(); 3457 AudioCodecType_T enmAudioCodec; 3458 hrc = audioAdapter->COMGETTER(AudioCodec)(&enmAudioCodec); H(); 3459 3460 GetExtraDataBoth(pVBox, pMachine, "VBoxInternal2/Audio/Device/TimerHz", &strTmp); 3461 const uint64_t uTimerHz = strTmp.toUInt64(); 3462 3463 GetExtraDataBoth(pVBox, pMachine, "VBoxInternal2/Audio/Device/BufSizeInMs", &strTmp); 3464 const uint64_t uBufSizeInMs = strTmp.toUInt64(); 3465 3466 GetExtraDataBoth(pVBox, pMachine, "VBoxInternal2/Audio/Device/BufSizeOutMs", &strTmp); 3467 const uint64_t uBufSizeOutMs = strTmp.toUInt64(); 3468 3469 GetExtraDataBoth(pVBox, pMachine, "VBoxInternal2/Audio/Debug/Enabled", &strTmp); 3470 const bool fDebugEnabled = strTmp.equalsIgnoreCase("true") || strTmp.equalsIgnoreCase("1"); 3471 3472 GetExtraDataBoth(pVBox, pMachine, "VBoxInternal2/Audio/Debug/Level", &strTmp); 3473 const uint32_t uDebugLevel = strTmp.toUInt32(); 3474 3475 Utf8Str strDebugPathOut; 3476 GetExtraDataBoth(pVBox, pMachine, "VBoxInternal2/Audio/Debug/PathOut", &strDebugPathOut); 3477 3478 #ifdef VBOX_WITH_AUDIO_VALIDATIONKIT 3479 GetExtraDataBoth(pVBox, pMachine, "VBoxInternal2/Audio/VaKit/Enabled", &strTmp); /* Deprecated; do not use! */ 3480 if (strTmp.isEmpty()) 3481 GetExtraDataBoth(pVBox, pMachine, "VBoxInternal2/Audio/ValKit/Enabled", &strTmp); 3482 /* Whether the Validation Kit audio backend runs as the primary backend. 3483 * Can also be used with VBox release builds. */ 3484 const bool fValKitEnabled = strTmp.equalsIgnoreCase("true") || strTmp.equalsIgnoreCase("1"); 3485 #endif 3486 /** @todo Implement an audio device class, similar to the audio backend class, to construct the common stuff 3487 * without duplicating (more) code. */ 3488 3489 const char *pszAudioDevice; 3490 switch (enmAudioController) 3491 { 3492 case AudioControllerType_AC97: 3493 { 3494 /* ICH AC'97. */ 3495 pszAudioDevice = "ichac97"; 3496 3497 InsertConfigNode(pDevices, pszAudioDevice, &pDev); 3498 InsertConfigNode(pDev, "0", &pInst); 3499 InsertConfigInteger(pInst, "Trusted", 1); /* boolean */ 3500 hrc = pBusMgr->assignPCIDevice(pszAudioDevice, pInst); H(); 3501 InsertConfigNode(pInst, "Config", &pCfg); 3502 switch (enmAudioCodec) 3503 { 3504 case AudioCodecType_STAC9700: 3505 InsertConfigString(pCfg, "Codec", "STAC9700"); 3506 break; 3507 case AudioCodecType_AD1980: 3508 InsertConfigString(pCfg, "Codec", "AD1980"); 3509 break; 3510 default: AssertFailedBreak(); 3511 } 3512 if (uTimerHz) 3513 InsertConfigInteger(pCfg, "TimerHz", uTimerHz); 3514 if (uBufSizeInMs) 3515 InsertConfigInteger(pCfg, "BufSizeInMs", uBufSizeInMs); 3516 if (uBufSizeOutMs) 3517 InsertConfigInteger(pCfg, "BufSizeOutMs", uBufSizeOutMs); 3518 InsertConfigInteger(pCfg, "DebugEnabled", fDebugEnabled); 3519 if (strDebugPathOut.isNotEmpty()) 3520 InsertConfigString(pCfg, "DebugPathOut", strDebugPathOut); 3521 break; 3522 } 3523 case AudioControllerType_SB16: 3524 { 3525 /* Legacy SoundBlaster16. */ 3526 pszAudioDevice = "sb16"; 3527 3528 InsertConfigNode(pDevices, pszAudioDevice, &pDev); 3529 InsertConfigNode(pDev, "0", &pInst); 3530 InsertConfigInteger(pInst, "Trusted", 1); /* boolean */ 3531 InsertConfigNode(pInst, "Config", &pCfg); 3532 InsertConfigInteger(pCfg, "IRQ", 5); 3533 InsertConfigInteger(pCfg, "DMA", 1); 3534 InsertConfigInteger(pCfg, "DMA16", 5); 3535 InsertConfigInteger(pCfg, "Port", 0x220); 3536 InsertConfigInteger(pCfg, "Version", 0x0405); 3537 if (uTimerHz) 3538 InsertConfigInteger(pCfg, "TimerHz", uTimerHz); 3539 InsertConfigInteger(pCfg, "DebugEnabled", fDebugEnabled); 3540 if (strDebugPathOut.isNotEmpty()) 3541 InsertConfigString(pCfg, "DebugPathOut", strDebugPathOut); 3542 break; 3543 } 3544 case AudioControllerType_HDA: 3545 { 3546 /* Intel HD Audio. */ 3547 pszAudioDevice = "hda"; 3548 3549 InsertConfigNode(pDevices, pszAudioDevice, &pDev); 3550 InsertConfigNode(pDev, "0", &pInst); 3551 InsertConfigInteger(pInst, "Trusted", 1); /* boolean */ 3552 hrc = pBusMgr->assignPCIDevice(pszAudioDevice, pInst); H(); 3553 InsertConfigNode(pInst, "Config", &pCfg); 3554 if (uBufSizeInMs) 3555 InsertConfigInteger(pCfg, "BufSizeInMs", uBufSizeInMs); 3556 if (uBufSizeOutMs) 3557 InsertConfigInteger(pCfg, "BufSizeOutMs", uBufSizeOutMs); 3558 InsertConfigInteger(pCfg, "DebugEnabled", fDebugEnabled); 3559 if (strDebugPathOut.isNotEmpty()) 3560 InsertConfigString(pCfg, "DebugPathOut", strDebugPathOut); 3561 3562 /* macOS guests uses a different HDA variant to make 10.14+ (or maybe 10.13?) recognize the device. */ 3563 if (fOsXGuest) 3564 InsertConfigString(pCfg, "DeviceName", "Intel Sunrise Point"); 3565 break; 3566 } 3567 default: 3568 pszAudioDevice = "oops"; 3569 AssertFailedBreak(); 3570 } 3571 3572 PCFGMNODE pCfgAudioAdapter = NULL; 3573 InsertConfigNode(pInst, "AudioConfig", &pCfgAudioAdapter); 3574 SafeArray<BSTR> audioProps; 3575 hrc = audioAdapter->COMGETTER(PropertiesList)(ComSafeArrayAsOutParam(audioProps)); H(); 3576 3577 std::list<Utf8Str> audioPropertyNamesList; 3578 for (size_t i = 0; i < audioProps.size(); ++i) 3579 { 3580 Bstr bstrValue; 3581 audioPropertyNamesList.push_back(Utf8Str(audioProps[i])); 3582 hrc = audioAdapter->GetProperty(audioProps[i], bstrValue.asOutParam()); 3583 Utf8Str strKey(audioProps[i]); 3584 InsertConfigString(pCfgAudioAdapter, strKey.c_str(), bstrValue); 3585 } 3586 3587 /* 3588 * The audio driver. 3589 */ 3590 const char *pszAudioDriver = NULL; 3591 #ifdef VBOX_WITH_AUDIO_VALIDATIONKIT 3592 if (fValKitEnabled) 3593 { 3594 pszAudioDriver = "ValidationKitAudio"; 3595 LogRel(("Audio: ValidationKit driver active\n")); 3596 } 3597 #endif 3598 /* If nothing else was selected before, ask the API. */ 3599 if (pszAudioDriver == NULL) 3600 { 3601 AudioDriverType_T enmAudioDriver; 3602 hrc = audioAdapter->COMGETTER(AudioDriver)(&enmAudioDriver); H(); 3603 3604 /* The "Default" audio driver needs special treatment, as we need to figure out which driver to use 3605 * by default on the current platform. */ 3606 bool const fUseDefaultDrv = enmAudioDriver == AudioDriverType_Default; 3607 3608 AudioDriverType_T const enmDefaultAudioDriver = settings::MachineConfigFile::getHostDefaultAudioDriver(); 3609 3610 if (fUseDefaultDrv) 3611 { 3612 enmAudioDriver = enmDefaultAudioDriver; 3613 if (enmAudioDriver == AudioDriverType_Null) 3614 LogRel(("Audio: Warning: No default driver detected for current platform -- defaulting to Null audio backend\n")); 3615 } 3616 3617 switch (enmAudioDriver) 3618 { 3619 case AudioDriverType_Default: /* Can't happen, but handle it anyway. */ 3620 RT_FALL_THROUGH(); 3621 case AudioDriverType_Null: 3622 pszAudioDriver = "NullAudio"; 3623 break; 3624 #ifdef RT_OS_WINDOWS 3625 # ifdef VBOX_WITH_WINMM 3626 case AudioDriverType_WinMM: 3627 # error "Port WinMM audio backend!" /** @todo Still needed? */ 3628 break; 3629 # endif 3630 case AudioDriverType_DirectSound: 3631 /* Use the Windows Audio Session (WAS) API rather than Direct Sound on Windows 3632 versions we've tested it on (currently W7+). Since Vista, Direct Sound has 3633 been emulated on top of WAS according to the docs, so better use WAS directly. 3634 3635 Set extradata value "VBoxInternal2/Audio/WindowsDrv" "dsound" to no use WasAPI. 3636 3637 Keep this hack for backwards compatibility (introduced < 7.0). 3638 */ 3639 GetExtraDataBoth(pVBox, pMachine, "VBoxInternal2/Audio/WindowsDrv", &strTmp); H(); 3640 if ( enmDefaultAudioDriver == AudioDriverType_WAS 3641 && ( strTmp.isEmpty() 3642 || strTmp.equalsIgnoreCase("was") 3643 || strTmp.equalsIgnoreCase("wasapi")) ) 3644 { 3645 /* Nothing to do here, fall through to WAS driver. */ 3646 } 3647 else 3648 { 3649 pszAudioDriver = "DSoundAudio"; 3650 break; 3651 } 3652 RT_FALL_THROUGH(); 3653 case AudioDriverType_WAS: 3654 if (enmDefaultAudioDriver == AudioDriverType_WAS) /* WAS supported? */ 3655 pszAudioDriver = "HostAudioWas"; 3656 else if (enmDefaultAudioDriver == AudioDriverType_DirectSound) 3657 { 3658 LogRel(("Audio: Warning: Windows Audio Session (WAS) not supported, defaulting to DirectSound backend\n")); 3659 pszAudioDriver = "DSoundAudio"; 3660 } 3661 break; 3662 #endif /* RT_OS_WINDOWS */ 3663 #ifdef RT_OS_SOLARIS 3664 case AudioDriverType_SolAudio: 3665 /* Should not happen, as the Solaris Audio backend is not around anymore. 3666 * Remove this sometime later. */ 3667 LogRel(("Audio: Warning: Solaris Audio is deprecated, please switch to OSS!\n")); 3668 LogRel(("Audio: Automatically setting host audio backend to OSS\n")); 3669 3670 /* Manually set backend to OSS for now. */ 3671 pszAudioDriver = "OSSAudio"; 3672 break; 3673 #endif 3674 #ifdef VBOX_WITH_AUDIO_OSS 3675 case AudioDriverType_OSS: 3676 pszAudioDriver = "OSSAudio"; 3677 break; 3678 #endif 3679 #ifdef VBOX_WITH_AUDIO_ALSA 3680 case AudioDriverType_ALSA: 3681 pszAudioDriver = "ALSAAudio"; 3682 break; 3683 #endif 3684 #ifdef VBOX_WITH_AUDIO_PULSE 3685 case AudioDriverType_Pulse: 3686 pszAudioDriver = "PulseAudio"; 3687 break; 3688 #endif 3689 #ifdef RT_OS_DARWIN 3690 case AudioDriverType_CoreAudio: 3691 pszAudioDriver = "CoreAudio"; 3692 break; 3693 #endif 3694 default: 3695 pszAudioDriver = "oops"; 3696 AssertFailedBreak(); 3697 } 3698 3699 if (fUseDefaultDrv) 3700 LogRel(("Audio: Detected default audio driver type is '%s'\n", pszAudioDriver)); 3701 } 3702 3703 BOOL fAudioEnabledIn = FALSE; 3704 hrc = audioAdapter->COMGETTER(EnabledIn)(&fAudioEnabledIn); H(); 3705 BOOL fAudioEnabledOut = FALSE; 3706 hrc = audioAdapter->COMGETTER(EnabledOut)(&fAudioEnabledOut); H(); 3707 3708 unsigned idxAudioLun = 0; 3709 3710 InsertConfigNodeF(pInst, &pLunL0, "LUN#%u", idxAudioLun); 3711 i_configAudioDriver(pVBox, pMachine, pLunL0, pszAudioDriver, !!fAudioEnabledIn, !!fAudioEnabledOut); 3712 idxAudioLun++; 3713 3714 #ifdef VBOX_WITH_AUDIO_VRDE 3715 /* Insert dummy audio driver to have the LUN configured. */ 3716 InsertConfigNodeF(pInst, &pLunL0, "LUN#%u", idxAudioLun); 3717 InsertConfigString(pLunL0, "Driver", "AUDIO"); 3718 { 3719 AudioDriverCfg DrvCfgVRDE(pszAudioDevice, 0 /* Instance */, idxAudioLun, "AudioVRDE", 3720 !!fAudioEnabledIn, !!fAudioEnabledOut); 3721 int vrc = mAudioVRDE->InitializeConfig(&DrvCfgVRDE); 3722 AssertRCStmt(vrc, throw ConfigError(__FUNCTION__, vrc, "mAudioVRDE->InitializeConfig failed")); 3723 } 3724 idxAudioLun++; 3725 #endif 3726 3727 #ifdef VBOX_WITH_AUDIO_RECORDING 3728 /* Insert dummy audio driver to have the LUN configured. */ 3729 InsertConfigNodeF(pInst, &pLunL0, "LUN#%u", idxAudioLun); 3730 InsertConfigString(pLunL0, "Driver", "AUDIO"); 3731 { 3732 AudioDriverCfg DrvCfgVideoRec(pszAudioDevice, 0 /* Instance */, idxAudioLun, "AudioVideoRec", 3733 false /*a_fEnabledIn*/, true /*a_fEnabledOut*/); 3734 int vrc = mRecording.mAudioRec->InitializeConfig(&DrvCfgVideoRec); 3735 AssertRCStmt(vrc, throw ConfigError(__FUNCTION__, vrc, "Recording.mAudioRec->InitializeConfig failed")); 3736 } 3737 idxAudioLun++; 3738 #endif 3739 3740 if (fDebugEnabled) 3741 { 3742 #ifdef VBOX_WITH_AUDIO_DEBUG 3743 # ifdef VBOX_WITH_AUDIO_VALIDATIONKIT 3744 /* 3745 * When both, ValidationKit and Debug mode (for audio) are enabled, 3746 * skip configuring the Debug audio driver, as both modes can 3747 * mess with the audio data and would lead to side effects. 3748 * 3749 * The ValidationKit audio driver has precedence over the Debug audio driver. 3750 * 3751 * This also can (and will) be used in VBox release builds. 3752 */ 3753 if (fValKitEnabled) 3754 { 3755 LogRel(("Audio: Warning: ValidationKit running and Debug mode enabled -- disabling Debug driver\n")); 3756 } 3757 else /* Debug mode active -- run both (nice for catching errors / doing development). */ 3758 { 3759 /* 3760 * The ValidationKit backend. 3761 */ 3762 InsertConfigNodeF(pInst, &pLunL0, "LUN#%u", idxAudioLun); 3763 i_configAudioDriver(pVBox, pMachine, pLunL0, "ValidationKitAudio", 3764 !!fAudioEnabledIn, !!fAudioEnabledOut); 3765 idxAudioLun++; 3766 # endif /* VBOX_WITH_AUDIO_VALIDATIONKIT */ 3767 /* 3768 * The Debug audio backend. 3769 */ 3770 InsertConfigNodeF(pInst, &pLunL0, "LUN#%u", idxAudioLun); 3771 i_configAudioDriver(pVBox, pMachine, pLunL0, "DebugAudio", 3772 !!fAudioEnabledIn, !!fAudioEnabledOut); 3773 idxAudioLun++; 3774 # ifdef VBOX_WITH_AUDIO_VALIDATIONKIT 3775 } 3776 # endif /* VBOX_WITH_AUDIO_VALIDATIONKIT */ 3777 #endif /* VBOX_WITH_AUDIO_DEBUG */ 3778 3779 /* 3780 * Tweak the logging groups. 3781 */ 3782 Utf8Str strGroups("drv_audio.e.l.l2.l3.f" 3783 " audio_mixer.e.l.l2.l3.f" 3784 " dev_hda_codec.e.l.l2.l3.f" 3785 " dev_hda.e.l.l2.l3.f" 3786 " dev_ac97.e.l.l2.l3.f" 3787 " dev_sb16.e.l.l2.l3.f"); 3788 3789 LogRel(("Audio: Debug level set to %RU32\n", uDebugLevel)); 3790 3791 switch (uDebugLevel) 3792 { 3793 case 0: 3794 strGroups += " drv_host_audio.e.l.l2.l3.f"; 3795 break; 3796 case 1: 3797 RT_FALL_THROUGH(); 3798 case 2: 3799 RT_FALL_THROUGH(); 3800 case 3: 3801 strGroups += " drv_host_audio.e.l.l2.l3.f+audio_test.e.l.l2.l3.f"; 3802 break; 3803 case 4: 3804 RT_FALL_THROUGH(); 3805 default: 3806 strGroups += " drv_host_audio.e.l.l2.l3.l4.f+audio_test.e.l.l2.l3.l4.f"; 3807 break; 3808 } 3809 3810 int vrc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), strGroups.c_str()); 3811 if (RT_FAILURE(vrc)) 3812 LogRel(("Audio: Setting debug logging failed, vrc=%Rrc\n", vrc)); 3813 } 3814 } 3815 3816 return VINF_SUCCESS; 3817 } 3818 3819 #undef H 3820 #undef VRC 3821 3424 3822 #ifndef VBOX_WITH_EFI_IN_DD2 3425 3823 DECLHIDDEN(int) findEfiRom(IVirtualBox* vbox, PlatformArchitecture_T aPlatformArchitecture, FirmwareType_T aFirmwareType, Utf8Str *pEfiRomFile)
Note:
See TracChangeset
for help on using the changeset viewer.