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

WASAPI built-in resampler: Add AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM flag #819

Closed
feoff3 opened this issue Aug 3, 2021 · 3 comments
Closed

Comments

@feoff3
Copy link

feoff3 commented Aug 3, 2021

I discovered that there is a built-in resampler in WASAPI that allows to use any wave format with WASAPI.
It is turned on by AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM flag , see
https://docs.microsoft.com/en-us/windows/win32/coreaudio/audclnt-streamflags-xxx-constants
The flag is succesfully used in miniaudio and portaudio C++ open source libraries.

Adding this option to NAudio WASAPI implementation would greatly simplify the life of Windows-based developers as manual resampling is cumbersome and sometimes results in pretty much unpredictable results. Use of something built-in instead looks like a more reliable and simple option.

I was wondering if it works in NAudio. I was able to change the NAudio code inserting the flag into NAudio lib+disabling IsFormatSupported() call for NAudio.Wasapi/WasapiCapture.cs.
This allowed me to specify any format for WasapiCapture even if it is not supported by the endpoint device.

For this, I changed AudioClientStreamFlags() code:

        protected AudioClientStreamFlags GetAudioClientStreamFlags()
        {
            // autoresampling flags. works starting from Win8
            uint AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM = 0x80000000;
            uint AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY = 0x08000000;
            uint streamFlags = AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY;
            return (AudioClientStreamFlags)streamFlags;
        }

and deleted IsFormatSupported() check from

if (!audioClient.IsFormatSupported(ShareMode, waveFormat))

Let me know how to proceed: propose a patch or let you incorporate this flag in a way you prefer (e.g. having a separate class, or whatever that suits NAudio code design)

@markheath
Copy link
Contributor

Wow, didn't know that was in there, and would be great to get in there (especially if this works for playback too)

In terms of fitting with NAudio design - a couple of thoughts

  1. I'd probably make auto-resampling optional but on by default. e.g. a class property that you can change before beginning capture
  2. I still think you need to check if the format is supported since the user could have asked for something unusual like MP3 format

@feoff3
Copy link
Author

feoff3 commented Aug 4, 2021

Thanks for sharing the thoughts:

  1. Agreed. I think changing the default behaviour posses some risk in terms of backward-compatbility but I can hardly imagine a client code that seeks for the best fitting format by simply trying out all the possible formats within a loop or something.
  2. Well, a sanity check for PCM\IEEE floating is needed indeed.

@markheath
Copy link
Contributor

Sorry it took me so long to get round to this, but finally have implemented it and it will be in the next NAudio release. Many thanks for making me aware of this capability - it makes WASAPI so much easier to work with.
Sadly, you can't use it with WASAPI exclusive mode playback, but that's not too surprising.

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

2 participants