如何解决为什么 PyAudio 会切断 NumPy 数组中的音频?
我在使用 PyAudio 时不小心忘记将一些 NumPy 数组转换为字节对象,但令我惊讶的是它仍然播放音频,即使听起来有点不对。我编写了一个小测试脚本(见下文)来播放 1 秒的 440Hz 音调,似乎将 NumPy 数组直接写入 PyAudio Stream
会缩短该音调。
谁能解释为什么会这样?我认为 NumPy 数组是一个连续的字节序列,其中包含一些有关其 dtype 和步幅的标头信息,因此我预测 PyAudio 在标头中出现一些乱码音频后会播放整整一秒的音调,而不是切断音调。
# script segment
import pyaudio
import numpy as np
RATE = 48000
p = pyaudio.PyAudio()
stream = p.open(format = pyaudio.paFloat32,channels = 1,rate = RATE,output = True)
TONE = 440
SECONDS = 1
t = np.arange(0,2*np.pi*TONE*SECONDS,2*np.pi*TONE/RATE)
sina = np.sin(t).astype(np.float32)
sinb = sina.tobytes()
# console commands segment
stream.write(sinb) # bytes object plays 1 second of 440Hz tone
stream.write(sina) # still plays 440Hz tone,but noticeably shorter than 1 second
解决方法
问题比您描述的更微妙。您的第一个调用是传递一个大小为 192,000 的字节数组。第二个调用是传递大小为 48,000 的 float32 值列表。 pyaudio
处理它们,并将缓冲区传递给 portaudio
进行播放。
但是,当您打开 pyaudio
时,您告诉它您正在发送 paFloat32
数据,每个样本有 4 个字节。 pyaudio write
处理程序采用您提供的数组的长度,并除以通道数乘以样本大小以确定有多少音频样本。在您的第二次调用中,数组的长度是 48,000,它除以 4,从而告诉 portaudio
“这里有 12,000 个样本”。
所以,每个人都理解格式,但对大小感到困惑。如果你把第二个电话改成
stream.write(sina,48000)
那么没有人需要猜测,它运行得非常好。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。