VirtualBox

Ignore:
Timestamp:
Oct 17, 2023 8:09:12 AM (15 months ago)
Author:
vboxsync
Message:

Main/ConsoleImpl: Move the audio controller configuration out of the x86 config constructor into a separate method in order to be able to use it from the Armv8 variant later on, bugref:10528

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/ConsoleImplConfigCommon.cpp

    r101318 r101458  
    4747#include "DisplayImpl.h"
    4848#include "NvramStoreImpl.h"
     49#include "BusAssignmentManager.h"
    4950#ifdef VBOX_WITH_DRAG_AND_DROP
    5051# include "GuestImpl.h"
     
    34223423
    34233424
     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
     3428int 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
    34243822#ifndef VBOX_WITH_EFI_IN_DD2
    34253823DECLHIDDEN(int) findEfiRom(IVirtualBox* vbox, PlatformArchitecture_T aPlatformArchitecture, FirmwareType_T aFirmwareType, Utf8Str *pEfiRomFile)
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