如何在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
- 将 portaudio 目录放在 pyaudio 中,名称为 portaudio-v19,名称很重要
- 安装MinGW/MSYS:我们需要的gcc、make和MSYS控制台
- 在 MSYS 控制台中 cd 到 portaudio-v19
./configure --with-winapi=wasapi --enable-shared=no
make
cd ..
更改这些行:
external_libraries += ['winmm']
extra_link_args += ['-lwinmm']
在 setup.py 中:
external_libraries += ["winmm","ole32","uuid"]
extra_link_args += ["-lwinmm","-lole32","-luuid"]
python setup.py build --static-link -cmingw32
python setup.py install --skip-build
就是这样。现在 pyadio 可以在 WASAPI 独占模式下播放声音了。
我正在使用 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
- 将 portaudio 目录放在 pyaudio 中,名称为 portaudio-v19,名称很重要
- 安装MinGW/MSYS:我们需要的gcc、make和MSYS控制台
- 在 MSYS 控制台中 cd 到 portaudio-v19
./configure --with-winapi=wasapi --enable-shared=no
make
cd ..
更改这些行:
external_libraries += ['winmm']
extra_link_args += ['-lwinmm']
在 setup.py 中:
external_libraries += ["winmm","ole32","uuid"]
extra_link_args += ["-lwinmm","-lole32","-luuid"]
python setup.py build --static-link -cmingw32
python setup.py install --skip-build
就是这样。现在 pyadio 可以在 WASAPI 独占模式下播放声音了。