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 :)
解决方案
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.