使用pyaudio时什么是块、样本和帧
What are chunks, samples and frames when using pyaudio
看了pyaudio的文档,看了网上的其他文章,不知自己的理解是否正确。
这是在pyaudio网站上找到的录音代码:
import pyaudio
import wave
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
如果我添加这些行,那么我就可以播放我录制的任何内容:
play=pyaudio.PyAudio()
stream_play=play.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
output=True)
for data in frames:
stream_play.write(data)
stream_play.stop_stream()
stream_play.close()
play.terminate()
- "RATE"是每秒收集的样本数。
- "CHUNK"是缓冲区中的帧数。
- 每帧将有 2 个样本作为 "CHANNELS=2"。
- 每个样本的大小为 2 个字节,使用函数计算:
pyaudio.get_sample_size(pyaudio.paInt16)
.
- 因此每个帧的大小为 4 个字节。
- 在"frames"列表中,每个元素的大小必须为1024*4字节,例如
frames[0]
的大小必须为4096字节。然而,
sys.getsizeof(frames[0])
returns4133
,但是len(frames[0])
returns4096
.
for
循环执行 int(RATE / CHUNK * RECORD_SECONDS)
次,我不明白为什么。 Here 是 "Ruben Sanchez" 回答的同一个问题,但我不能确定他说的是否正确 CHUNK=bytes
。根据他的解释,它必须是 int(RATE / (CHUNK*2) * RECORD_SECONDS)
,因为 (CHUNK*2)
是每次迭代在缓冲区中读取的样本数。
- 最后,当我写
print frames[0]
时,它打印出乱码,因为它试图将字符串视为 ASCII 编码,但实际上它不是,它只是一个字节流。那么如何使用 struct
模块以十六进制打印这个字节流呢?如果稍后,我用我选择的值更改每个十六进制值,它仍然会产生可播放的声音吗?
上面写的都是我对事情的理解,可能有很多是错误的。
- "RATE"是"sampling rate",即每秒帧数
- "CHUNK" 是 帧的(任意选择的)数量 在这个例子中(可能很长)信号被分割成
- 是的,每个帧将有 2 个样本作为 "CHANNELS=2",但术语 "samples" 很少用于此上下文(因为它令人困惑)
- 是的,本例中每个样本的大小为 2 个字节(= 16 位)
- 是的,每帧大小为4字节
- 是的,"frames"的每个元素应该是4096字节。
sys.getsizeof()
报告 Python 解释器所需的存储 space,这通常比原始数据的实际大小多一点。
RATE * RECORD_SECONDS
是应该记录的 帧 的数量。由于 for
循环不会对每个 frame 重复,而只会对每个 chunk 重复,因此循环次数必须除以块大小 CHUNK
。这与samples无关,所以不涉及2
的因素。
- 如果你真的想看到十六进制值,你可以试试
[hex(x) for x in frames[0]]
。如果您想获得实际的 2 字节数字,请使用带有 struct
模块的格式字符串 '<H'
。
您可能对我关于使用 wave
模块读取 WAV 文件的教程感兴趣,其中更详细地涵盖了您的一些问题:http://nbviewer.jupyter.org/github/mgeier/python-audio/blob/master/audio-files/audio-files-with-wave.ipynb
看了pyaudio的文档,看了网上的其他文章,不知自己的理解是否正确。
这是在pyaudio网站上找到的录音代码:
import pyaudio
import wave
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
如果我添加这些行,那么我就可以播放我录制的任何内容:
play=pyaudio.PyAudio()
stream_play=play.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
output=True)
for data in frames:
stream_play.write(data)
stream_play.stop_stream()
stream_play.close()
play.terminate()
- "RATE"是每秒收集的样本数。
- "CHUNK"是缓冲区中的帧数。
- 每帧将有 2 个样本作为 "CHANNELS=2"。
- 每个样本的大小为 2 个字节,使用函数计算:
pyaudio.get_sample_size(pyaudio.paInt16)
. - 因此每个帧的大小为 4 个字节。
- 在"frames"列表中,每个元素的大小必须为1024*4字节,例如
frames[0]
的大小必须为4096字节。然而,sys.getsizeof(frames[0])
returns4133
,但是len(frames[0])
returns4096
. for
循环执行int(RATE / CHUNK * RECORD_SECONDS)
次,我不明白为什么。 Here 是 "Ruben Sanchez" 回答的同一个问题,但我不能确定他说的是否正确CHUNK=bytes
。根据他的解释,它必须是int(RATE / (CHUNK*2) * RECORD_SECONDS)
,因为(CHUNK*2)
是每次迭代在缓冲区中读取的样本数。- 最后,当我写
print frames[0]
时,它打印出乱码,因为它试图将字符串视为 ASCII 编码,但实际上它不是,它只是一个字节流。那么如何使用struct
模块以十六进制打印这个字节流呢?如果稍后,我用我选择的值更改每个十六进制值,它仍然会产生可播放的声音吗?
上面写的都是我对事情的理解,可能有很多是错误的。
- "RATE"是"sampling rate",即每秒帧数
- "CHUNK" 是 帧的(任意选择的)数量 在这个例子中(可能很长)信号被分割成
- 是的,每个帧将有 2 个样本作为 "CHANNELS=2",但术语 "samples" 很少用于此上下文(因为它令人困惑)
- 是的,本例中每个样本的大小为 2 个字节(= 16 位)
- 是的,每帧大小为4字节
- 是的,"frames"的每个元素应该是4096字节。
sys.getsizeof()
报告 Python 解释器所需的存储 space,这通常比原始数据的实际大小多一点。 RATE * RECORD_SECONDS
是应该记录的 帧 的数量。由于for
循环不会对每个 frame 重复,而只会对每个 chunk 重复,因此循环次数必须除以块大小CHUNK
。这与samples无关,所以不涉及2
的因素。- 如果你真的想看到十六进制值,你可以试试
[hex(x) for x in frames[0]]
。如果您想获得实际的 2 字节数字,请使用带有struct
模块的格式字符串'<H'
。
您可能对我关于使用 wave
模块读取 WAV 文件的教程感兴趣,其中更详细地涵盖了您的一些问题:http://nbviewer.jupyter.org/github/mgeier/python-audio/blob/master/audio-files/audio-files-with-wave.ipynb