【发布时间】:2021-04-07 04:55:35
【问题描述】:
简而言之
有没有办法将原始音频数据(通过PyAudio模块获取)转换成虚拟文件的形式(可以使用python的open()函数获取),而无需保存到磁盘并从磁盘?详情如下。
我在做什么
我正在使用PyAudio 录制音频,然后将其输入到张量流模型中进行预测。目前,当我首先将录制的声音保存为磁盘上的.wav文件时,它可以工作,然后再次读取它以将其输入模型。下面是记录和保存的代码:
import pyaudio
import wave
CHUNK_LENGTH = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
RECORD_SECONDS = 1
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK_LENGTH)
print("* recording")
frames = [stream.read(RATE * RECORD_SECONDS)] # here is the recorded data, in the form of list of bytes
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
在我得到原始音频数据(变量frames)后,可以使用pythonwave模块保存如下。我们可以看到,在保存的时候,必须调用wf.setxxx这样的函数来保存一些元消息。
import os
output_dir = "data/"
output_path = output_dir + "{:%Y%m%d_%H%M%S}.wav".format(datetime.now())
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# save the recorded data as wav file using python `wave` module
wf = wave.open(output_path, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
这是使用保存的文件在 tensorflow 模型上运行推理的代码。它只是简单地将其读取为二进制,然后模型将处理其余部分。
import classifier # my tensorflow model
with open(output_path, 'rb') as f:
w = f.read()
classifier.run_graph(w, labels, 5)
问题
为了满足实时需求,我需要不断地流式传输音频并偶尔将其馈送到模型中。但是继续将文件保存在磁盘上然后一遍又一遍地读取它似乎是不合理的,这会浪费在 I/O 上的时间。
我想将数据保存在内存中并直接使用,而不是反复保存和读取。但是pythonwave模块不支持同时读写(参考here)。
如果我直接输入没有一些元数据(例如通道、帧率)的数据(可以在保存过程中由wave 模块添加),如下所示:
w = b''.join(frames)
classifier.run_graph(w, labels, 5)
我会得到如下错误:
2021-04-07 11:05:08.228544: W tensorflow/core/framework/op_kernel.cc:1651] OP_REQUIRES failed at decode_wav_op.cc:55 : Invalid argument: Header mismatch: Expected RIFF but found
Traceback (most recent call last):
File "C:\Users\anaconda3\envs\tensorflow\lib\site-packages\tensorflow_core\python\client\session.py", line 1365, in _do_call
return fn(*args)
File "C:\Users\anaconda3\envs\tensorflow\lib\site-packages\tensorflow_core\python\client\session.py", line 1350, in _run_fn
target_list, run_metadata)
File "C:\Users\anaconda3\envs\tensorflow\lib\site-packages\tensorflow_core\python\client\session.py", line 1443, in _call_tf_sessionrun
run_metadata)
tensorflow.python.framework.errors_impl.InvalidArgumentError: 2 root error(s) found.
(0) Invalid argument: Header mismatch: Expected RIFF but found
这里提供了我正在使用的 tensorflow 模型:ML-KWS-for-MCU,希望对您有所帮助。
这是产生错误的代码:(classifier.run_graph())
def run_graph(wav_data, labels, num_top_predictions):
"""Runs the audio data through the graph and prints predictions."""
with tf.Session() as sess:
# Feed the audio data as input to the graph.
# predictions will contain a two-dimensional array, where one
# dimension represents the input image count, and the other has
# predictions per class
softmax_tensor = sess.graph.get_tensor_by_name("labels_softmax:0")
predictions, = sess.run(softmax_tensor, {"wav_data:0": wav_data})
# Sort to show labels in order of confidence
top_k = predictions.argsort()[-num_top_predictions:][::-1]
for node_id in top_k:
human_string = labels[node_id]
score = predictions[node_id]
print('%s (score = %.5f)' % (human_string, score))
return 0
【问题讨论】:
-
您是否尝试过使用 BytesIO 对象?
-
@MadPhysicist 如果你的意思是用
io.BytesIO()包装数据,tensorflow 会说tensorflow.python.framework.errors_impl.InternalError: Unsupported object type _io.BytesIO -
你在使用前是否倒带文件?
-
发布你是如何得到错误的。一般来说,Tensorflow 似乎与 io.BytesIO 配合得很好。
-
@MadPhysicist 已发布。对tensorflow不熟悉,只知道需要wav数据,类型为bytes
标签: python tensorflow pyaudio wave