【发布时间】:2014-09-18 09:19:31
【问题描述】:
如何将实时音频读入 numpy 数组并使用 matplotlib 进行绘图?
现在我正在 wav 文件上录制音频,然后使用 scikits.audiolab.wavread 将其读入数组。
有没有办法可以直接实时执行此操作?
【问题讨论】:
如何将实时音频读入 numpy 数组并使用 matplotlib 进行绘图?
现在我正在 wav 文件上录制音频,然后使用 scikits.audiolab.wavread 将其读入数组。
有没有办法可以直接实时执行此操作?
【问题讨论】:
您可以使用PyAudio 录制音频并使用np.frombuffer 将其转换为numpy 数组。
import pyaudio
import numpy as np
from matplotlib import pyplot as plt
CHUNKSIZE = 1024 # fixed chunk size
# initialize portaudio
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=44100, input=True, frames_per_buffer=CHUNKSIZE)
# do this as long as you want fresh samples
data = stream.read(CHUNKSIZE)
numpydata = np.frombuffer(data, dtype=np.int16)
# plot data
plt.plot(numpydata)
plt.show()
# close stream
stream.stop_stream()
stream.close()
p.terminate()
如果要录制立体声而不是单声道,则必须将 channels 设置为 2。然后你得到一个带有交错通道的数组。你可以像这样重塑它:
frame = np.frombuffer(data, dtype=numpy.int16) # interleaved channels
frame = np.stack((frame[::2], frame[1::2]), axis=0) # channels on separate axes
【讨论】:
alsaaudio 而不是pyaudio。两者有区别吗?
alsaaudio 仅适用于 Linux,而 PyAudio 提供 PortAudio-bindings 并适用于多个平台。
有一个名为PyAudio 的库。您可以使用它来实时录制。加上numpy.fromstring() 和numpy.hstack() 的帮助,您可以获得所需的输出。请注意,下面的 sn-p 是针对MONO-CHANNEL。
import pyaudio
import numpy
RATE=16000
RECORD_SECONDS = 2.5
CHUNKSIZE = 1024
# initialize portaudio
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=RATE, input=True, frames_per_buffer=CHUNKSIZE)
frames = [] # A python-list of chunks(numpy.ndarray)
for _ in range(0, int(RATE / CHUNKSIZE * RECORD_SECONDS)):
data = stream.read(CHUNKSIZE)
frames.append(numpy.fromstring(data, dtype=numpy.int16))
#Convert the list of numpy-arrays into a 1D array (column-wise)
numpydata = numpy.hstack(frames)
# close stream
stream.stop_stream()
stream.close()
p.terminate()
这是经过测试的代码。它应该作为魅力。为了检查您记录的数据是否在numpydata中正确可用,您可以在前面的代码之后添加以下sn-p。
import scipy.io.wavfile as wav
wav.write('out.wav',RATE,numpydata)
这些行会将您的numpydata 写入“out.wav”。播放文件检查数据。
PS:这是我在 StackOverflow 中的第一个回复。希望对您有所帮助。
【讨论】:
import librosa
file = 'audio/a1.wav'
signal, _ = librosa.load(file)
print(type(signal))
【讨论】:
此答案与此处的第一个答案相似,但我已经包含了绘制音频数据的缺失部分。
import pyaudio
import wave
import numpy as np
import noisereduce as nr
#This library helps us in plotting the audio
import matplotlib.pyplot as plt
def plotAudio2(output):
fig, ax = plt.subplots(nrows=1,ncols=1, figsize=(20,4))
plt.plot(output, color='blue')
ax.set_xlim((0, len(output)))
plt.show()
CHUNK = 22050
FORMAT = pyaudio.paFloat32
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 20
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)
data_sample = np.frombuffer(data, dtype=np.float32)
print("data sample")
plotAudio2(data_sample)
stream.stop_stream()
stream.close()
p.terminate()
我已经测试了上面的代码 sn-p,这对我来说非常好。
注意:此代码 sn-p 在 Windows 中测试过,matplotlib 在 MacOS 中可能存在问题(我不确定)
【讨论】: