質問

I need to play 2 sounds simultaneously, with multiprocessing rather than threads, to see if it solves a problem where threads play the audio in sequence rather than in parallel. I am guessing it's due to the Global Interpreter Lock (GIL) in python.

I added a question 2 days ago, but my description is overcomplicated. This is the simple version:

The audio gets imported as numpy array. I take this array and play it using the scikits.audiolab module:

import scikits.audiolab as audiolab

# This is how I import my wav file. "frames" is the numpy array, "fs" = sampling 
# frequency, "encoder" = quantizing at 16 bits

frames, fs, encoder = audiolab.wavread('audio.wav')

# This is how I play my wav file. audiolab plays the frames array at a frequency of 
# 44100 Hz
audiolab.play(frames, fs=44100)

That's fine, but this is what I need help on: playing 2 files at the same time using multiprocessing.

frames1, fs1, encoder1 = audiolab.wavread('audio1.wav')
frames2, fs2, encoder2 = audiolab.wavread('audio2.wav')

audiolab.play(frames1, fs=44100)
audiolab.play(frames2, fs=44100)
役に立ちましたか?

解決

If you want to have any control over the relative timing of the two sounds (for example, they should start simultaneously), using multiple processes is probably not a good solution. You should be mixing the signals within your application and writing out a single audio stream.

Since you are using audiolab, you already have the data in numpy arrays. This gives you all the flexibility you need to mix audio:

frames1, fs1, encoder1 = audiolab.wavread('audio1.wav')
frames2, fs2, encoder2 = audiolab.wavread('audio2.wav')
mixed = frames1 + frames2

audiolab.play(mixed, fs=44100)

If this causes the audio signal to clip (you hear clicks / pops), you may need to pre-scale the data before mixing:

mixed = frames1 / 2 + frames2 / 2

.. and if the sounds do not have equal length, it may take a little more work:

mixed = np.zeros(max(len(frames1), len(frames2)), dtype=frames1.dtype)
mixed[:len(frames1)] += frames1 / 2
mixed[:len(frames2)] += frames2 / 2

他のヒント

The better way to approach this is to use a library that already knows how to mix audio streams -- two different processes trying to share the audio hardware is at best a wonky way to address this problem.

Look at Pygame or PyAudio (Python bindings to PortAudio).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top