2
votes

I'm using these precompiled binaries of pyaudio with WASAPI support. I want to play a wav file via WASAPI. I found index of default output device for this api:

import pyaudio

p = pyaudio.PyAudio()

print p.get_host_api_info_by_index(3)
>>{'index': 3, 'name': u'Windows WASAPI', 'defaultOutputDevice': 11L, 'type': 13L, 'deviceCount': 3L, 'defaultInputDevice': 12L, 'structVersion': 1L}

Then I play a wav file via this device:

import pyaudio
import wave

CHUNK = 1024

wf = wave.open('test.wav', 'rb')

# instantiate PyAudio (1)
p = pyaudio.PyAudio()

# open stream (2)
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                channels=wf.getnchannels(),
                rate=wf.getframerate(),
                output_device_index=11,
                output=True)

# read data
data = wf.readframes(CHUNK)

# play stream (3)
while data != '':
    stream.write(data)
    data = wf.readframes(CHUNK)

# stop stream (4)
stream.stop_stream()
stream.close()

# close PyAudio (5)
p.terminate()

When file is playing I'm still able to hear another sounds in the system, but in exclusive WASAPI mode all other sounds must be blocked. So how to enable WASAPI exclusive mode in pyaudio?

1

1 Answers

2
votes

There is need to change sources of pyaudio. We need to modify _portaudiomodule.c.

Include pa_win_wasapi.h:

#include pa_win_wasapi.h

Change this line:

outputParameters->hostApiSpecificStreamInfo = NULL;

On this:

struct PaWasapiStreamInfo wasapiInfo;
wasapiInfo.size = sizeof(PaWasapiStreamInfo);
wasapiInfo.hostApiType = paWASAPI;
wasapiInfo.version = 1;
wasapiInfo.flags = (paWinWasapiExclusive|paWinWasapiThreadPriority);
wasapiInfo.threadPriority = eThreadPriorityProAudio;

outputParameters->hostApiSpecificStreamInfo = (&wasapiInfo);

Now we need to compile pyaudio.

  1. Place portaudio dir in pyaudio with name portaudio-v19, name is important
  2. Install MinGW/MSYS: gcc, make and MSYS console we need
  3. In MSYS console cd to portaudio-v19
  4. ./configure --with-winapi=wasapi --enable-shared=no
  5. make
  6. cd ..
  7. change these lines:

    external_libraries += ['winmm']

    extra_link_args += ['-lwinmm']

    in setup.py on these:

    external_libraries += ["winmm","ole32","uuid"]

    extra_link_args += ["-lwinmm","-lole32","-luuid"]

  8. python setup.py build --static-link -cmingw32
  9. python setup.py install --skip-build

That's all. Now pyadio is able to play sound in WASAPI exclusive mode.