Regarding inability of Python Module Winsound to produce beep in decimal frequency

Eryk Sun eryksun at gmail.com
Tue Aug 17 18:23:19 EDT 2021


On 8/17/21, Dennis Lee Bieber <wlfraed at ix.netcom.com> wrote:
> On Tue, 17 Aug 2021 15:11:05 +1000, Chris Angelico <rosuav at gmail.com>
> declaimed the following:
>
>>Huh. Okay. Then I withdraw the concern from this list, and instead lay
>>it at Microsoft's feet. That is, I maintain, a bizarre choice. Surely
>>there are better ways to trigger audio on the sound card?
>
> 	Possibly there is a section of code that determines if a sound card is
> available, and if not, routes to the basic internal speaker. The rest of
> the wave form logic is probably still of use for that.

It may be that there's a fallback audio device that uses the PC
speaker on systems that lack even basic audio support in their
chipset. But in common practice, Beep() does not use the PC speaker.

The "beep.sys" driver in Windows 7+ has no code path that starts a PC
speaker beep via HalMakeBeep(frequency) and ends it after a timeout
via HalMakeBeep(0), which was the old implementation of "beep.sys"
that can still be seen in ReactOS [1].

The HAL (hardware abstraction layer) function HalMakeBeep() is still
implemented in Windows 10, but without the connection to an IOCTL in
"\Device\Beep", or some other installed device driver, there's no way
for user-mode code to make a beep with the classic PC speaker.

In Windows 7+, the beep device's IOCTL_BEEP_SET function is just a
relay. It's implemented by searching for and completing a queued IOCTL
request from a task in the user's session (i.e. an inverted callback
from kernel mode to user mode). This task, which is scheduled to run
at logon in every interactive session, executes the "PlaySoundSrv.dll"
module in an instance of "taskhostw.exe". Upon completion of its
queued IOCTL, from which it gets the beep frequency and duration, the
sound server generates the requested beep waveform and plays it on the
default audio output device via WinAPI PlaySound().

Notably, the "beep.sys" driver doesn't support manually starting the
sound-server task in the user's session. So if one terminates the
"taskhostw.exe" process that's hosting "PlaySoundSrv.dll", WinAPI
Beep() will no longer work. To get it back, the
"\Microsoft\Windows\Multimedia\SystemSoundsService" task has to be
restarted manually.

---

[1] https://github.com/reactos/reactos/blob/master/drivers/base/beep/beep.c#L295


More information about the Python-list mailing list