Reputation: 81
I'm new to PyAudio and audio manipulation so this is a really basic question I haven't found the answer for -- PyAudio gives you the option of sending sound to different channels via a channel map, but how do you get those different channels hooked up to your computer/python?
Is it as simple as, for example, pairing a bluetooth speaker and thus having my computer's internal speakers as one channel and the bluetooth speaker as a second?
(Ultimately I'd like to play 2 .wav files simultaneously but separately on 2 different outputs. If there's an easier way of doing this than with PyAudio, open to hearing about that, too!)
Thanks for your help! :)
Upvotes: 3
Views: 4280
Reputation: 11473
I believe this may be possible using sounddevice. See link for install details.
sounddevice
provides an easy way to list different input/output audio devices using sd.query_devices()
>>> print sd.query_devices()
0 Microsoft Sound Mapper - Input, MME (2 in, 0 out)
> 1 Jack Mic (IDT High Definition A, MME (2 in, 0 out)
2 Microphone Array (IDT High Defi, MME (2 in, 0 out)
3 Microsoft Sound Mapper - Output, MME (0 in, 2 out)
< 4 Speakers / Headphones (IDT High, MME (0 in, 2 out)
5 Communication Headphones (IDT H, MME (0 in, 2 out)
Here device id (4) is output device (speakers). I don't have bluetooth
configured. But if you have, it should show in the list.
Once both output devices are listed, you can simply redirect them using
sd.play(data_array, sampling_frequency, device=device_id_)
While sounddevice
has limitation of blocking IO while playback is in progress, I believe it can be overcome by the use of threading.
NOTE: Following code is not tested on two different devices. Let me know if it works.
import sounddevice as sd
import soundfile as sf
import threading
from threading import Thread
def audioFunc1():
audio1 = "audio1.wav"
data1, fs1 = sf.read(audio1, dtype='float32')
sd.play(data1, fs1, device=3) #speakers
def audioFunc2():
audio2 = "audio2.wav"
data2, fs2 = sf.read(audio2, dtype='float32')
sd.play(data2, fs2, device=10) #headset
if __name__ == '__main__':
Thread(target = audioFunc1).start()
Thread(target = audioFunc2).start()
Upvotes: 3