Чтение аудиоданных в реальном времени в массив numpy

как я могу читать аудио в реальном времени в массив numpy и использовать matplotlib для построения графика?

Сейчас я записываю аудио в файл wav, а затем scikits.audiolab.wavread читаю его в массив. Есть ли способ сделать это прямо в реальном времени?

Ответ 1

Вы можете использовать PyAudio для записи аудио и использовать np.frombuffer чтобы преобразовать его в пустой массив.

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

Ответ 2

Существует библиотека под названием PyAudio. Вы можете использовать его для записи в режиме реального времени. Плюс с помощью numpy.fromstring() и numpy.hstack() вы можете получить желаемый результат. Обратите внимание, что следующий фрагмент для 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, вы можете добавить следующий фрагмент кода после предыдущего кода.

import scipy.io.wavefile as wav
wav.write('out.wav',RATE,numpydata)

Эти строки будут записывать ваш numpydata в "out.wav". Загрузите файл, чтобы проверить данные.

PS: Это мой первый ответ в StackOverflow. Надеюсь, что это поможет.