如何在pyaudio中启用WASAPI独占模式

How to enable WASAPI exclusive mode in pyaudio

我正在使用 these 支持 WASAPI 的 pyaudio 预编译二进制文件。我想通过 WASAPI 播放一个 wav 文件。我找到了此 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}

然后我通过这个设备播放一个wav文件:

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()

当文件正在播放时,我仍然能够听到系统中的其他声音,但在独占 WASAPI 模式下,所有其他声音都必须被阻止。那么如何在pyaudio中启用WASAPI独占模式呢?

需要更改 pyaudio 的来源。我们需要修改_portaudiomodule.c.

包括pa_win_wasapi.h:

#include pa_win_wasapi.h

更改此行:

outputParameters->hostApiSpecificStreamInfo = NULL;

关于这个:

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

outputParameters->hostApiSpecificStreamInfo = (&wasapiInfo);

现在我们需要编译pyaudio

  1. 将 portaudio 目录放在 pyaudio 中,名称为 portaudio-v19,名称很重要
  2. 安装MinGW/MSYS:我们需要的gcc、make和MSYS控制台
  3. 在 MSYS 控制台中 cd 到 portaudio-v19
  4. ./configure --with-winapi=wasapi --enable-shared=no
  5. make
  6. cd ..
  7. 更改这些行:

    external_libraries += ['winmm']

    extra_link_args += ['-lwinmm']

    在 setup.py 中:

    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

就是这样。现在 pyadio 可以在 WASAPI 独占模式下播放声音了。