如何使用 matplotlib 绘制 pyaudio 输入?

Dus*_* J. 1 python speech-recognition matplotlib

如何绘制来自麦克风的 matplotlib 输入信号?我尝试用 plt.plot(frames) 进行绘图,但由于某种原因,frames 是一个字符串?

a) 为什么frames变量是一个字符串列表?

b) 为什么数据变量是字符串列表?

c) 它们应该代表单个样本的能量/幅度并且是整数吗?

d) 当我指定块大小为 1024 时,为什么数据长度为 2048?

(我猜是因为我使用 paInt16,但仍然看不出为什么它不能是 1024)

我有以下用于麦克风输入的代码:

import pyaudio
import audioop
import matplotlib.pyplot as plt
import numpy as np
from itertools import izip
import wave


FORMAT = pyaudio.paInt16                # We use 16bit format per sample
CHANNELS = 1
RATE = 44100
CHUNK = 1024                            # 1024bytes of data red from a buffer
RECORD_SECONDS = 3
WAVE_OUTPUT_FILENAME = "file.wav"

audio = pyaudio.PyAudio()

# start Recording
stream = audio.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE, input=True,
                    frames_per_buffer=CHUNK)

frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)
frames = ''.join(frames)

stream.stop_stream()
stream.close()
audio.terminate()
Run Code Online (Sandbox Code Playgroud)

fja*_*rri 5

a) 为什么frames变量是一个字符串列表?

由于 b),这就是您在代码中构建它的方式。

b) 为什么数据变量是字符串列表?

它是一个字节字符串,只是原始的字节序列。这就是read()返回的结果。

c) 它们应该代表单个样本的能量/幅度并且是整数吗?

他们是。它们只是打包在字节序列中,而不是 Python 整数中。

d) 当我指定块大小为 1024 时,为什么数据长度为 2048?

1024帧数。每帧长 2 个字节,因此您得到 2048 个字节。

如何绘制来自麦克风的 matplotlib 输入信号?我尝试用 plt.plot(frames) 进行绘图,但由于某种原因,frames 是一个字符串?

取决于你想要绘制什么内容。通过将字节字符串转换为 numpy 数组可以获得原始幅度:

fig = plt.figure()
s = fig.add_subplot(111)
amplitude = numpy.fromstring(frames, numpy.int16)
s.plot(amplitude)
fig.savefig('t.png')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

更有用的图是频谱图

fig = plt.figure()
s = fig.add_subplot(111)
amplitude = numpy.fromstring(frames, numpy.int16)
s.specgram(amplitude)
fig.savefig('t.png')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是既然你有了一个numpy数组,你就可以随意修改幅度。

  • `numpy` 无法从原始字节字符串推断出存储在那里的变量类型,您必须明确指定它。由于数据被读取为“pyaudio.paInt16”,因此该字符串包含 2 字节有符号整数,这就是我告诉“numpy”读取的内容。 (2认同)