On a windows 10, with no headphones plugged in:
DirectSoundCreate8 returns S_OK
IDirectSoundBuffer8::Play returns 0x8889000F (potentially AUDCLNT_E_ENDPOINT_CREATE_FAILED)
and this is the first call to return any error.
On a windows 7, with no headphones plugged in:
DirectSoundCreate8 returns DSERR_NODRIVER;
The problem is, if the Play() call is the first call to return that anything is amiss, I have to have already loaded and decoded a sound (expensive) just to figure that I can't play sounds...
This seems crazy so I must be doing something wrong.
The behavior difference here is that Windows 10 / Windows 11 is using Virtual Audio Devices for WASAPI, while Windows 7 version of WASAPI does not support virtual audio devices.
The reason virtual audio devices were introduced is because WASAPI end-points come and go as the speakers/headphones are plugged and unplugged. WASAPI clients had to handle this scenario by destroying and reattaching to end-points. For XAudio2 API users, this was surfaced as an 'on-critical-error' that required games to destroy and re-create their audio graphs as sound devices were physically removed. With the new virtualized behavior, WASAPI moves the end-points around automatically.
DirectSound has had various levels of emulation since Windows Vista, and its behavior is mostly tuned for appcompat with existing titles. This list of limitations for DirectSound has been true since Windows Vista:
LOC_HARDWAREbuffers are unsupported.Surround-sound (beyond stereo) buffers are supported as
LOC_SOFTWARE(on Windows XP, these had to beLOC_HARDWARE).Effects (I3DL, EAX, etc.) are not supported through DirectSound.
DirectSound 3D audio continues to support only mono channel sounds, while XAudio2 supports multi-channel 3D audio.
Appcompat shim are applied in some cases to redirect the 'default' device from
DSDEVID_DefaultPlaybacktoDSDEVID_DefaultVoicePlayback(orDSDEVID_DefaultCapture->DSDEVID_DefaultVoiceCapturefor capture).I'm not aware of any 'opt-out' flag for the virtualized audio device for DirectSound, but if you enumerate an audio device via
DirectSoundEnumerateand use that GUID instead of the default device, it will likely bypass it.