Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The CoreAudioController slow at InnerEnumerator.EnumAudioEndpoints #72

Open
EzEddinM opened this issue Dec 13, 2023 · 2 comments
Open

Comments

@EzEddinM
Copy link

The CoreControlAudio is slow because of the InnerEnumerator.EnumAudioEndpoints(EDataFlow.All, EDeviceState.All, out collection);
Namespace AudioSwitcher.AudioApi.CoreAudio, class CoreAudioController , Line 46
AudioSwitcher.AudioApi.CoreAudio/CoreAudioController.cs
, EDeviceState.All => will it be possible to create a new constructor with EDeviceState as a parameter?

something like this:

public CoreAudioController(EDeviceState eDeviceState)

and change the InnerEnumerator.EnumAudioEndpoints to InnerEnumerator.EnumAudioEndpoints(EDataFlow.All, eDeviceState, out collection);

`Code:

    public CoreAudioController(EDeviceState eDeviceState)
    {
        // ReSharper disable once SuspiciousTypeConversion.Global
        var innerEnumerator = ComObjectFactory.GetDeviceEnumerator();
        _innerEnumeratorPtr = Marshal.GetIUnknownForObject(innerEnumerator);

        if (innerEnumerator == null)
            throw new InvalidComObjectException("No Device Enumerator");

        _innerEnumerator = new ThreadLocal<IMultimediaDeviceEnumerator>(() => Marshal.GetUniqueObjectForIUnknown(_innerEnumeratorPtr) as IMultimediaDeviceEnumerator);

        ComThread.Invoke(() =>
        {
            _systemEvents = new SystemEventNotifcationClient(() => InnerEnumerator);

            _systemEvents.DeviceAdded.Subscribe(x => OnDeviceAdded(x.DeviceId));
            _systemEvents.DeviceRemoved.Subscribe(x => OnDeviceRemoved(x.DeviceId));

            _deviceCache = new HashSet<CoreAudioDevice>();
            IMultimediaDeviceCollection collection;
            InnerEnumerator.EnumAudioEndpoints(EDataFlow.All, eDeviceState, out collection);

            using (var coll = new MultimediaDeviceCollection(collection))
            {
                foreach (var mDev in coll)
                    CacheDevice(mDev);
            }
        });
    }

`

so if you do it we can get the Devices that we need and not all Devices.

Use of the constructor will be somthing like this:

CoreAudioController coreAudioController = new AudioSwitcher.AudioApi.CoreAudio.CoreAudioController(EDeviceState.Active);

@xenolightning
Copy link
Owner

I'm not sure the actual issue is with fetching all the system devices, but I believe it's in the CacheDevice method, where it's trying to do way too much work.

This constructor is doing far too much, and is really inefficient, in hindsight the work should probably be done during an initialization phase.

Either way, I think the correct solution is to fix the CacheDevice (and probably the AudioDevice constructor)

@project-sbc
Copy link

seeing similar delay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants