为什么 PyAudio 会切断 NumPy 数组的音频?
Why does PyAudio cut off audio from NumPy array?
我在使用 PyAudio 时不小心忘记了将一些 NumPy 数组转换为字节 objects,但令我惊讶的是它仍然 播放了音频,即使听起来有点不对劲.我写了一个小测试脚本(见下文)来播放 1 秒的 440Hz 音调,似乎将 NumPy 数组直接写入 PyAudio Stream
会缩短音调。
谁能解释为什么会这样?我认为 NumPy 数组是一个连续的字节序列,其中包含一些关于其 dtype 和步幅的 header 信息,所以我会预测 PyAudio 在 header, 不切音.
# 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)
那就没人猜了,而且效果很好。
我在使用 PyAudio 时不小心忘记了将一些 NumPy 数组转换为字节 objects,但令我惊讶的是它仍然 播放了音频,即使听起来有点不对劲.我写了一个小测试脚本(见下文)来播放 1 秒的 440Hz 音调,似乎将 NumPy 数组直接写入 PyAudio Stream
会缩短音调。
谁能解释为什么会这样?我认为 NumPy 数组是一个连续的字节序列,其中包含一些关于其 dtype 和步幅的 header 信息,所以我会预测 PyAudio 在 header, 不切音.
# 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)
那就没人猜了,而且效果很好。