Ana Olano
Ana Olano

Reputation: 81

How to connect multiple audio output channels for use with PyAudio?

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

Answers (1)

Anil_M
Anil_M

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

Related Questions