How to play sound in Python WITHOUT interrupting m

2020-07-10 06:47发布

问题:

I'm working on a timer in python which sounds a chime when the waiting time is over. I use the following code:

from wave import open as wave_open
from ossaudiodev import open as oss_open

def _play_chime():
    """
    Play a sound file once.

    """
    sound_file = wave_open('chime.wav','rb')
    (nc,sw,fr,nf,comptype, compname) = sound_file.getparams( )
    dsp = oss_open('/dev/dsp','w')
    try:
      from ossaudiodev import AFMT_S16_NE
    except ImportError:
      if byteorder == "little":
        AFMT_S16_NE = ossaudiodev.AFMT_S16_LE
      else:
        AFMT_S16_NE = ossaudiodev.AFMT_S16_BE
    dsp.setparameters(AFMT_S16_NE, nc, fr)
    data = sound_file.readframes(nf)
    sound_file.close()
    dsp.write(data)
    dsp.close()

It works pretty good, unless any other device is already outputing sound.

How could I do basically the same (under linux) without having the prerequisite that no sound is being played?

If you think the process would require an API to ensure software mixing, please suggest a method :)

Thx for the support :)

回答1:

The easy answer is "Switch from OSS to PulseAudio." (Or set up ALSA to use dmix, or get a soundcard with better Linux drivers...)

The more complicated answer is, your code already works the way you want it to... on some soundcards. OSS drivers can expose hardware mixers so that you can have multiple audio streams playing simultaneously, or they can expose a single stream which results in the blocking audio you see on your system. The only correct solution here is to use an API that ensures software mixing.



回答2:

Modern hardware and drivers supports multiple streams. So unless you are running with ancient hardware or a crappy driver, it should work anyway.

Having said that, ALSA may give you more control than OSS. Most kernels shipped nowadays support both.