我需要使用Python 3捕获192 kHz音频以进行一些生物声学实验。 我有硬件,声音设备USBPre 2声卡,麦克风具有高达100 kHz的良好频率响应曲线,我已经启用了我的操作系统(ubuntu 13.04)以192 kHz的频率从该卡中采样。
我尝试用PyAudio录音。它似乎工作,并将给我一个采样率为192 kHz的wav文件。然而,当我观察光谱时,没有超过24 kHz的功率,这表明PyAudio不是真正捕获192 kHz,而是48 kHz。但是,当我使用Audacity录制来自JACK的输入时,我得到了一个很好的录音,功率高达96kHz。所以,我的印象是PyAudio实际上并没有以192 kHz采样声音,即使它应该能够。 如何解决这个问题?
我没有错误地启动JACK:
/usr/bin/jackd -R -dalsa -Chw:1,0 -n3 -o1 -p2048 -r192000
jackd 0.122.0
Copyright 2001-2009 Paul Davis, Stephane Letz, Jack O'Quinn, Torben Hohn and others.
jackd comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details
JACK compiled with System V SHM support.
loading driver ..
apparent rate = 192000
creating alsa driver ... -|hw:1,0|2048|3|192000|0|1|nomon|swmeter|-|32bit
control device hw:0
configuring for 192000Hz, period = 2048 frames (10.7 ms), buffer = 3 periods
ALSA: final selected sample format for capture: 24bit little-endian
ALSA: use 3 periods for capture
初始化PyAudio(没有任何实际错误(据我所知)):
p = pyaudio.PyAudio()
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
bt_audio_service_open: connect() failed: Connection refused (111)
bt_audio_service_open: connect() failed: Connection refused (111)
bt_audio_service_open: connect() failed: Connection refused (111)
bt_audio_service_open: connect() failed: Connection refused (111)
ALSA lib pcm_dmix.c:957:(snd_pcm_dmix_open) The dmix plugin supports only playback stream
打开PyAudio流:
stream = p.open(format=pyaudio.paInt32,
channels=1,rate=192000,
input=True,
frames_per_buffer=2048)
我有光谱图的图像,如果有人想验证我的解释,PyAudio不能以192 kHz捕获(但Audacity确实如此):
使用PyAudio捕获声音的频谱图
拍摄声音的频谱图使用Audacity
如何使用PyAudio以192 000样本/秒的速度录制声音? 我们也欢迎使用Python 3捕获声音的其他方法的建议。
答案 0 :(得分:5)
这并不是一个确凿的答案,而是试图帮助您自己追踪问题。
当尝试在OS X上使用PyAudio重现您的问题时,我总是遇到[Errno Input overflowed] -9981
(例如several其他people,seems)。
p.is_format_supported()
报告为OK的配置也会导致这些错误。所以我制作了一个脚本,试图记录录制设置的所有可能的排列。
此脚本会探测设备,采样率,格式和频道列表的所有排列防御方式,并将结果保存到根据录制设置命名的文件。
import os
import pyaudio
import sys
# === These parameters will be permuted ===========
DEVICES = [0, 1, 2]
RATES = [44100, 48000, 192000]
FORMATS = ['Float32', 'Int32', 'Int24', 'Int16', 'Int8', 'UInt8']
CHANNELS = [1, 2]
# =================================================
CHUNK = 1024
COLUMNS = (('filename', 30),
('result', 9),
('dev', 5),
('rate', 8),
('format', 9),
('channels', 10),
('chunk', 7),
('reason', 0))
STATUS_MSG = "Recording... "
pa = pyaudio.PyAudio()
def get_format(format):
fmt = getattr(pyaudio, 'pa%s' % format)
return fmt
def record(filename=None,
duration=5,
dev=0,
rate=44100,
format='Float32',
channels=2,
chunk=1024,):
"""Record `duration` seconds of audio from the device with index `dev`.
Store the result in a file named according to recording settings.
"""
if filename is None:
filename = "dev{dev}-{rate}-{format}-{channels}ch.raw".format(**locals())
result = 'FAILURE'
reason = ''
outfile = open(filename, 'w')
print STATUS_MSG,
sys.stdout.flush()
try:
stream = pa.open(input_device_index=dev,
rate=rate,
format=get_format(format),
channels=channels,
frames_per_buffer=chunk,
input=True,
)
try:
for i in range(0, rate / (chunk) * duration):
a = stream.read(chunk)
outfile.write(a)
result = 'SUCCESS'
# Catch exceptions when trying to read from stream
except Exception, e:
reason = "'%s'" % e
# Catch exceptions when trying to even open the stream
except Exception, e:
reason = "'%s'" % e
outfile.close()
# Don't leave files behind for unsuccessful attempts
if result == 'FAILURE':
os.remove(filename)
filename = ''
info = {}
for col_name, width in COLUMNS:
info[col_name] = str(locals()[col_name]).ljust(width)
msg = "{filename}{result}{dev}{rate}{format}{channels}{chunk}{reason}"
print msg.format(**info)
def main():
# Build the header line
header = 'STATUS'.ljust(len(STATUS_MSG) + 1)
for col_name, width in COLUMNS:
header += col_name.upper().ljust(width)
print header
print "=" * len(header)
# Record samples for all permutations of our parameter lists
for dev in DEVICES:
for rate in RATES:
for format in FORMATS:
for channels in CHANNELS:
record(duration=2,
dev=dev,
rate=rate,
format=format,
channels=channels,
chunk=CHUNK)
if __name__ == '__main__':
main()
示例输出(简化):
STATUS FILENAME RESULT DEV RATE FORMAT CHANNELS CHUNK REASON
==================================================================================================
Recording... dev0-44100-Float32-1ch.raw SUCCESS 0 44100 Float32 1 1024
Recording... dev0-44100-Float32-2ch.raw SUCCESS 0 44100 Float32 2 1024
Recording... dev0-44100-Int16-1ch.raw SUCCESS 0 44100 Int16 1 1024
Recording... dev0-44100-Int16-2ch.raw SUCCESS 0 44100 Int16 2 1024
Recording... FAILURE 0 192000 Float32 1 1024 '[Errno Input overflowed] -9981'
Recording... FAILURE 0 192000 Float32 2 1024 '[Errno Input overflowed] -9981'
Recording... FAILURE 0 192000 Int16 1 1024 '[Errno Input overflowed] -9981'
Recording... FAILURE 0 192000 Int16 2 1024 '[Errno Input overflowed] -9981'
Recording... dev1-44100-Float32-1ch.raw SUCCESS 1 44100 Float32 1 1024
Recording... dev1-44100-Float32-2ch.raw SUCCESS 1 44100 Float32 2 1024
Recording... dev1-44100-Int16-1ch.raw SUCCESS 1 44100 Int16 1 1024
Recording... dev1-44100-Int16-2ch.raw SUCCESS 1 44100 Int16 2 1024
Recording... FAILURE 1 192000 Float32 1 1024 '[Errno Input overflowed] -9981'
Recording... FAILURE 1 192000 Float32 2 1024 '[Errno Input overflowed] -9981'
Recording... FAILURE 1 192000 Int16 1 1024 '[Errno Input overflowed] -9981'
Recording... FAILURE 1 192000 Int16 2 1024 '[Errno Input overflowed] -9981'
Recording... FAILURE 2 44100 Float32 1 1024 '[Errno Invalid number of channels] -9998'
Recording... FAILURE 2 44100 Float32 2 1024 '[Errno Invalid number of channels] -9998'
Recording... FAILURE 2 44100 Int16 1 1024 '[Errno Invalid number of channels] -9998'
Recording... FAILURE 2 44100 Int16 2 1024 '[Errno Invalid number of channels] -9998'
Recording... FAILURE 2 192000 Float32 1 1024 '[Errno Invalid number of channels] -9998'
Recording... FAILURE 2 192000 Float32 2 1024 '[Errno Invalid number of channels] -9998'
Recording... FAILURE 2 192000 Int16 1 1024 '[Errno Invalid number of channels] -9998'
Recording... FAILURE 2 192000 Int16 2 1024 '[Errno Invalid number of channels] -9998'