Skip to content

servers [windows]: select WASAPI as default device if available#6994

Merged
dyfer merged 1 commit intosupercollider:3.14from
dyfer:topic/select-wasapi-Windows
Jun 23, 2025
Merged

servers [windows]: select WASAPI as default device if available#6994
dyfer merged 1 commit intosupercollider:3.14from
dyfer:topic/select-wasapi-Windows

Conversation

@dyfer
Copy link
Member

@dyfer dyfer commented Jun 16, 2025

Purpose and Motivation

Use WASAPI for the default device selection on Windows.

We seem to need this before we can disable old APIs, see #6900 (comment)

Types of changes

  • New feature (?)

To-do list

  • Code is tested
  • All tests are passing
  • Updated documentation
  • This PR is ready for review

@dyfer
Copy link
Member Author

dyfer commented Jun 16, 2025

@Spacechild1 how does this look to you?
My only concern is that apiInfo->default[In/Out]putDevice could theoretically return noPaDevice and I wonder if we should call Pa_GetDefault... when that happens?
ButPa_GetDefaultInputDevice()/Pa_GetDefaultOutputDevice() can also return noPaDevice so maybe this is an edge case anyway.

@dyfer dyfer force-pushed the topic/select-wasapi-Windows branch 2 times, most recently from 382d172 to 3ac4c94 Compare June 17, 2025 17:42
@Spacechild1
Copy link
Contributor

Spacechild1 commented Jun 20, 2025

I don't have time to actually test myself, but looks good to me!

My only concern is that apiInfo->default[In/Out]putDevice could theoretically return noPaDevice and I wonder if we should call Pa_GetDefault... when that happens?

Actually, we should not do that because we might end up with two devices with different APIs. For example, take a laptop with no built-in microphone input, but a generic ASIO driver: GetPaDefaultDevice would return the ASIO driver as the input device and WASAPI speakers as the output device.

I'd suggest to add a comment to GetPaDefaultDevice and explain why we do not fall back to Pa_GetDefault[Input|Ouput]Device on noPaDevice.

@dyfer dyfer force-pushed the topic/select-wasapi-Windows branch from 3ac4c94 to 4dc5415 Compare June 20, 2025 17:00
@Spacechild1
Copy link
Contributor

I just tried this locally. From my side side this is good to go!

@Spacechild1 Spacechild1 self-requested a review June 20, 2025 20:55
@dyfer
Copy link
Member Author

dyfer commented Jun 20, 2025

Thanks @Spacechild1
Do you think we should push it to 3.14.0 or 3.14.1 ? I thought that maybe it would be nice to introduce this default in a release so that it's widely tested, before we go ahead and remove old APIs (which could happen in 3.15).
But maybe there's no rush...

@Spacechild1
Copy link
Contributor

I think this can definitely go to 3.14. I would rather not do this in a bug fix release.

@dyfer
Copy link
Member Author

dyfer commented Jun 20, 2025

I would rather not do this in a bug fix release.

Do you mean - yes in 3.14.0 but not in 3.14.1 ?

@dyfer dyfer changed the base branch from develop to 3.14 June 20, 2025 21:26
@Spacechild1
Copy link
Contributor

Yes!

@capital-G
Copy link
Contributor

if this goes into 3.14 we definitely need a 3.14-rc2

@dyfer
Copy link
Member Author

dyfer commented Jun 20, 2025

Yes, we need rc2 anyway, I think.
I think it would be good to have this in, despite it not being technically a bugfix from rc1, as this really is the desired behavior on Windows (unless some terrible incompatibility emerges in wider testing...)

BTW this wasn't feasible until Christof's relatively recent PR to enable resampling in WASAPI, that's why we haven't had this for so long.

@capital-G
Copy link
Contributor

I don't have any clue about windows anymore, but if it helps and is not a big change I think its fine to bring this into 3.14 via rc2 ;)

@dyfer
Copy link
Member Author

dyfer commented Jun 20, 2025

All right! In that case I'll merge this.

@dyfer
Copy link
Member Author

dyfer commented Jun 20, 2025

To be extra safe:
@prko @sternsc would you be able to test a build from this PR on your Windows systems? Boot the server with a default device and make sure the sound works fine? Thanks!

@prko
Copy link
Contributor

prko commented Jun 21, 2025

Here are two results:


Windows 11 ARM:

Booting server 'localhost' on address 127.0.0.1:57110.

Device options:
- MME : Microsoft Sound Mapper - Input
  (2 ins, 0 outs)
- MME : Microphone (High Definition Aud
  (2 ins, 0 outs)
- MME : Microsoft Sound Mapper - Output
  (0 ins, 2 outs)
- MME : Speakers (High Definition Audio
  (0 ins, 8 outs)
- Windows DirectSound : Primary Sound Capture Driver
  (2 ins, 0 outs)
- Windows DirectSound : Microphone (High Definition Audio Device)
  (2 ins, 0 outs)
- Windows DirectSound : Primary Sound Driver
  (0 ins, 2 outs)
- Windows DirectSound : Speakers (High Definition Audio Device)
  (0 ins, 8 outs)
- Windows WASAPI : Speakers (High Definition Audio Device)
  (0 ins, 2 outs)
- Windows WASAPI : Microphone (High Definition Audio Device)
  (2 ins, 0 outs)
- Windows WDM-KS : Microphone (HD Audio Microphone)
  (2 ins, 0 outs)
- Windows WDM-KS : Speakers (HD Audio Speaker)
  (0 ins, 8 outs)

Requested devices:
  In:
  - (default)
  Out:
  - (default)

Selecting default system input/output devices

Booting with:
  In: Windows WASAPI : Microphone (High Definition Audio Device)
  Out: Windows WASAPI : Speakers (High Definition Audio Device)
  Sample rate: 48000.000
  Latency (in/out): 0.022 / 0.024 sec
SC_AudioDriver: sample rate = 48000.000000, driver's block size = 64
SuperCollider 3 server ready.
Requested notification messages from server 'localhost'
localhost: server process's maxLogins (1) matches with my options.
localhost: keeping clientID (0) as confirmed by server process.
Shared memory server interface initialized

Windows 10 ARM:


Device options:
- MME : Microsoft Sound Mapper - Input
  (2 ins, 0 outs)
- MME : Microphone (High Definition Aud
  (2 ins, 0 outs)
- MME : Microsoft Sound Mapper - Output
  (0 ins, 2 outs)
- MME : Speakers (High Definition Audio
  (0 ins, 8 outs)
- Windows DirectSound : Primary Sound Capture Driver
  (2 ins, 0 outs)
- Windows DirectSound : Microphone (High Definition Audio Device)
  (2 ins, 0 outs)
- Windows DirectSound : Primary Sound Driver
  (0 ins, 2 outs)
- Windows DirectSound : Speakers (High Definition Audio Device)
  (0 ins, 8 outs)
- Windows WASAPI : Speakers (High Definition Audio Device)
  (0 ins, 2 outs)
- Windows WASAPI : Microphone (High Definition Audio Device)
  (2 ins, 0 outs)
- Windows WDM-KS : Microphone (HD Audio Microphone)
  (2 ins, 0 outs)
- Windows WDM-KS : Speakers (HD Audio Speaker)
  (0 ins, 8 outs)

Requested devices:
  In:
  - (default)
  Out:
  - (default)

Selecting default system input/output devices

Booting with:
  In: Windows WASAPI : Microphone (High Definition Audio Device)
  Out: Windows WASAPI : Speakers (High Definition Audio Device)
  Sample rate: 48000.000
  Latency (in/out): 0.022 / 0.024 sec
SC_AudioDriver: sample rate = 48000.000000, driver's block size = 64
SuperCollider 3 server ready.
Requested notification messages from server 'localhost'
localhost: server process's maxLogins (1) matches with my options.
localhost: keeping clientID (0) as confirmed by server process.
Shared memory server interface initialized

@prko
Copy link
Contributor

prko commented Jun 22, 2025

I have tested with Windows 10 (x64) and Windows 11 (64) on Parallels Desktop on iMac 2013 (intel i7).
The test results are successful as above.


Windows 10 (x64)

Booting server 'localhost' on address 127.0.0.1:57110.

Device options:
- MME : Microsoft Sound Mapper - Input
  (2 ins, 0 outs)
- MME : Microphone (High Definition Aud
  (2 ins, 0 outs)
- MME : Microsoft Sound Mapper - Output
  (0 ins, 2 outs)
- MME : Speakers (High Definition Audio
  (0 ins, 8 outs)
- Windows DirectSound : Primary Sound Capture Driver
  (2 ins, 0 outs)
- Windows DirectSound : Microphone (High Definition Audio Device)
  (2 ins, 0 outs)
- Windows DirectSound : Primary Sound Driver
  (0 ins, 2 outs)
- Windows DirectSound : Speakers (High Definition Audio Device)
  (0 ins, 8 outs)
- Windows WASAPI : Speakers (High Definition Audio Device)
  (0 ins, 2 outs)
- Windows WASAPI : Microphone (High Definition Audio Device)
  (2 ins, 0 outs)
- Windows WDM-KS : Speakers (HD Audio Speaker)
  (0 ins, 8 outs)
- Windows WDM-KS : Microphone (HD Audio Microphone)
  (2 ins, 0 outs)

Requested devices:
  In:
  - (default)
  Out:
  - (default)

Selecting default system input/output devices

Booting with:
  In: Windows WASAPI : Microphone (High Definition Audio Device)
  Out: Windows WASAPI : Speakers (High Definition Audio Device)
  Sample rate: 48000.000
  Latency (in/out): 0.022 / 0.024 sec
SC_AudioDriver: sample rate = 48000.000000, driver's block size = 64
SuperCollider 3 server ready.
Requested notification messages from server 'localhost'
localhost: server process's maxLogins (1) matches with my options.
localhost: keeping clientID (0) as confirmed by server process.
Requested notification messages from server 'localhost'
/notify : already registered
localhost - already registered with clientID 0.
localhost - handling login request though already registered - 
This seems to be a login after a loss of network contact - 
- reconnected with the same clientID as before, so probably all is well.

Shared memory server interface initialized

Windows 11 (x64)

Booting server 'localhost' on address 127.0.0.1:57110.

Device options:
- MME : Microsoft Sound Mapper - Input
  (2 ins, 0 outs)
- MME : Microphone (High Definition Aud
  (2 ins, 0 outs)
- MME : Microsoft Sound Mapper - Output
  (0 ins, 2 outs)
- MME : 스피커 (High Definition Audio Devi
  (0 ins, 8 outs)
- Windows DirectSound : Primary Sound Capture Driver
  (2 ins, 0 outs)
- Windows DirectSound : Microphone (High Definition Audio Device)
  (2 ins, 0 outs)
- Windows DirectSound : Primary Sound Driver
  (0 ins, 2 outs)
- Windows DirectSound : 스피커 (High Definition Audio Device)
  (0 ins, 8 outs)
- ASIO : ASIO4ALL v2
  (2 ins, 8 outs)
- ASIO : Generic Low Latency ASIO Driver
  (2 ins, 2 outs)
- Windows WASAPI : 스피커 (High Definition Audio Device)
  (0 ins, 2 outs)
- Windows WASAPI : Microphone (High Definition Audio Device)
  (2 ins, 0 outs)
- Windows WDM-KS : Speakers (HD Audio Speaker)
  (0 ins, 8 outs)
- Windows WDM-KS : Microphone (HD Audio Microphone)
  (2 ins, 0 outs)

Requested devices:
  In:
  - (default)
  Out:
  - (default)

Selecting default system input/output devices

Booting with:
  In: Windows WASAPI : Microphone (High Definition Audio Device)
  Out: Windows WASAPI : 스피커 (High Definition Audio Device)
  Sample rate: 48000.000
  Latency (in/out): 0.022 / 0.024 sec
SC_AudioDriver: sample rate = 48000.000000, driver's block size = 64
SuperCollider 3 server ready.
Requested notification messages from server 'localhost'
localhost: server process's maxLogins (1) matches with my options.
localhost: keeping clientID (0) as confirmed by server process.
Shared memory server interface initialized

@dyfer
Copy link
Member Author

dyfer commented Jun 23, 2025

@prko did you try playing sound in your tests by any chance? Does it work fine with now dropouts etc (comparing to the MME driver)?

@sternsc
Copy link

sternsc commented Jun 23, 2025 via email

@prko
Copy link
Contributor

prko commented Jun 23, 2025

The following is a result on a real machine:

Windows 10 x64:

Booting server 'localhost' on address 127.0.0.1:57110.

Device options:
- MME : Microsoft Sound Mapper - Input
  (2 ins, 0 outs)
- MME : Microphone (Realtek High Defini
  (2 ins, 0 outs)
- MME : Microsoft Sound Mapper - Output
  (0 ins, 2 outs)
- MME : Speakers (Realtek High Definiti
  (0 ins, 2 outs)
- Windows DirectSound : Primary Sound Capture Driver
  (2 ins, 0 outs)
- Windows DirectSound : Microphone (Realtek High Definition Audio)
  (2 ins, 0 outs)
- Windows DirectSound : Primary Sound Driver
  (0 ins, 2 outs)
- Windows DirectSound : Speakers (Realtek High Definition Audio)
  (0 ins, 2 outs)
- Windows WASAPI : Speakers (Realtek High Definition Audio)
  (0 ins, 2 outs)
- Windows WASAPI : Microphone (Realtek High Definition Audio)
  (2 ins, 0 outs)
- Windows WDM-KS : Speakers (Realtek HD Audio output)
  (0 ins, 2 outs)
- Windows WDM-KS : Stereo Mix (Realtek HD Audio Stereo input)
  (2 ins, 0 outs)
- Windows WDM-KS : Microphone (Realtek HD Audio Mic input)
  (2 ins, 0 outs)
- Windows WDM-KS : Microphone (Parallels Access Sound Waveout)
  (2 ins, 0 outs)
- Windows WDM-KS : Speakers (Parallels Access Sound Waveout)
  (0 ins, 2 outs)

Requested devices:
  In:
  - (default)
  Out:
  - (default)

Selecting default system input/output devices

Booting with:
  In: Windows WASAPI : Microphone (Realtek High Definition Audio)
  Out: Windows WASAPI : Speakers (Realtek High Definition Audio)
  Sample rate: 48000.000
  Latency (in/out): 0.022 / 0.023 sec
SC_AudioDriver: sample rate = 48000.000000, driver's block size = 64
SuperCollider 3 server ready.
Requested notification messages from server 'localhost'
localhost: server process's maxLogins (1) matches with my options.
localhost: keeping clientID (0) as confirmed by server process.
Shared memory server interface initialized

I tested the following code firestly:

(
// Dust randomly triggers Decay to create an exponential
// decay envelope for the WhiteNoise input source
{
z = Decay.ar(Dust.ar(1, 0.5), 0.3, WhiteNoise.ar);
DelayC.ar(z, 0.2, 0.2, 1, z); // input is mixed with delay via the add input
}.play
)

It was successful.
Then I tested the following code after freeing the sound process above:

(
{
	z = SoundIn.ar(0);
	DelayC.ar([z, 0], 2, SinOsc.ar(1/60), 0.1, [0, z]); // input is mixed with delay via the add input
}.play
)

Although I could see the sound level on the s.meter, I could not hear any sound.
I quit the server and the interpreter. After starting Sclang and booting the server, everything worked.

There are no dropouts on this real machine:

Processor Intel(R) Core(TM) i3-3220T CPU @ 2.80GHz 2.80 GHz
Installed RAM 8.00 GB (7.89 GB usable)
Storage 932 GB SSD Samsung SSD 870 EVO 1TB
Graphics Card Intel(R) HD Graphics (32 MB)
System Type 64-bit operating system, x64-based processor
Pen and touch No pen or touch input is available for this display

@dyfer
Copy link
Member Author

dyfer commented Jun 23, 2025

Thanks for testing @prko !

@dyfer
Copy link
Member Author

dyfer commented Jun 23, 2025

After additional testing I'm now merging this, so that we include it in 3.14.0-rc2.

@dyfer dyfer merged commit b390407 into supercollider:3.14 Jun 23, 2025
25 checks passed
@prko
Copy link
Contributor

prko commented Jun 24, 2025

Sorry for the delay in the sound test. On the virtual machine, there are always dropouts, so I could not test the sound on my MacBook Pro.

@dyfer
Copy link
Member Author

dyfer commented Jun 24, 2025

Thanks! But are the dropouts worse than when using a MME device?
(I also found a VM to have dropouts typically)

@prko
Copy link
Contributor

prko commented Jun 24, 2025

@Spacechild1
Copy link
Contributor

I think WASAPI drops more sound.

That's not surprising, given that MME's default output latency is 4x larger than WASAPI's (92 ms vs 23 ms). On an actual Windows machine, you shouldn't get any dropouts in either case. (23 ms is still a pretty big buffer size.) Your other test confirmed this.

As @dyfer already noted, VMs are known for having audio issues. If you experience dropouts, just increase the hardware buffer size. (4096 roughly matches the MME default.)

@sternsc
Copy link

sternsc commented Jun 26, 2025

@dyfer Sorry for the delay; I have now tried the PR "3.15.0-dev" on Win10 and Win11, with a startup file that doesn't specify anything audio. On booting the server, all the APIs are still listed, and it selects WASAPI on the default audio device(s). This is as intended, I believe. Good!

@dyfer
Copy link
Member Author

dyfer commented Jul 16, 2025

My only concern is that apiInfo->default[In/Out]putDevice could theoretically return noPaDevice and I wonder if we should call Pa_GetDefault... when that happens?

Actually, we should not do that because we might end up with two devices with different APIs. For example, take a laptop with no built-in microphone input, but a generic ASIO driver: GetPaDefaultDevice would return the ASIO driver as the input device and WASAPI speakers as the output device.

I'd suggest to add a comment to GetPaDefaultDevice and explain why we do not fall back to Pa_GetDefault[Input|Ouput]Device on noPaDevice.

@Spacechild1 from a test in CI I believe this is not correct after all.

When running the current version on a system with only an ASIO device, the server now doesn't select ASIO as the default device (presumably because we get noPaDevice) and doesn't boot: https://github.com/supercollider/supercollider/actions/runs/16325805905/job/46116611466#step:6:230

Separately we have logic to handle different APIs, so I think we should always return a default device from the GetPaDefaultDevice function. I tried this on the windows tests PR and the tests now seem to run.

I think we need to fix this for 3.14 and make rc3, what do you think?

EDIT: fix submitted in #7051

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants