Python - Using multiple flags for winsound?

主宰稳场 提交于 2021-02-08 08:51:01

问题


This is my current code:

import winsound as wav

wav.PlaySound("music.wav", wav.SND_LOOP | wav.SND_ASYNC)
input()
wav.PlaySound("beep.wav", wav.SND_ASYNC | wav.SND_NOSTOP)

From the python winsound documentation: "[Winsound's] interpretation [of the file] depends on the value of flags, which can be a bitwise ORed combination of the constants described below"

The music itself plays asynchronously, and loops. However, when the above code plays the beep, it throws an error (sprites.py is the code's file):

Traceback (most recent call last):
  File ".../sprites.py", line 5, in <module>
    wav.PlaySound("beep.wav", wav.SND_ASYNC | wav.SND_NOSTOP)
RuntimeError: Failed to play sound

Swapping SND_ASYNC and SND_NOSTOP produces an identical error, and removing the SND_NOSTOP results in the beep playing, but the music cuts out.

Why is this happening, and if it's unfixable, is there another way I can cause the beep to play without cutting off the music?

The Sound files are here, if that's important.

This question exists, however it does not appear to have an answer.


回答1:


You are combing flags just fine; that's not the issue. The problem is that the API you are using doesn't support playing more than one sound at a time.

In other words, the exception is thrown because there is already a sound being played, in a loop. The SND_NOSTOP flag is only of use when you want to prevent a currently playing sound from being interrupted; the exception is raised to indicate that sound is playing right now. Without the flag the old sound is stopped and the new sound is played.

The winsound Python module is little more than a thin wrapper around the Windows API PlaySound function, which states:

SND_NOSTOP
The specified sound event will yield to another sound event that is already playing in the same process. If a sound cannot be played because the resource needed to generate that sound is busy playing another sound, the function immediately returns FALSE without playing the requested sound.

If this flag is not specified, PlaySound attempts to stop any sound that is currently playing in the same process. Sounds played in other processes are not affected.

Use the flag to optimistically play sounds only if nothing else is currently playing:

try:
    wav.PlaySound("beep.wav", wav.SND_ASYNC | wav.SND_NOSTOP)
except RuntimeError:
    # sound api busy with another sound, tough luck
    pass

In order to play sounds simultaneously you need an API that can mix sounds; PlaySound can't do this, and there is nothing else in the standard library that can.

You need something than lets you use the DirectSound API instead. Like the pyglet library. This library includes an excellent audio API that should make it trivial to combine looped music with occasional other sound effects playing in parallel.



来源:https://stackoverflow.com/questions/44492900/python-using-multiple-flags-for-winsound

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!