Ada Xu
Ada Xu

Reputation: 983

Reading realtime audio data into numpy array

how can I read real-time audio into numpy array and use matplotlib to plot ?

Right Now I am recording audio on an wav file then using scikits.audiolab.wavread to read it into an array. Is there a way I could do this directly in realtime?

Upvotes: 24

Views: 35530

Answers (4)

Ananth Kamath
Ananth Kamath

Reputation: 598

This answer is similar to the first answer here, but I have included missing part of plotting the Audio Data.

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()

I have tested above code snippet, this worked for me perfectly fine.

Note: This code snippet was tested in Windows, and matplotlib might have some issue in MacOS (I am not sure though)

Upvotes: 0

erptocoding
erptocoding

Reputation: 383

import librosa
file = 'audio/a1.wav'
signal, _ = librosa.load(file)
print(type(signal))

Upvotes: -1

stitchesguy90
stitchesguy90

Reputation: 383

There is a library called PyAudio. You can use it to record in real-time. Plus with the help of numpy.fromstring() and numpy.hstack(), you can get the desired output. Please note that the following snippet is for 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()

This is a tested code. It should work as charm. In order to check if your recorded data is correctly available in numpydata, you can add this following snippet after the previous code.

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

These lines will write your numpydata into "out.wav". Play the file to check the data.

PS: This is my first response in StackOverflow. Hope it helps.

Upvotes: 22

Frank Zalkow
Frank Zalkow

Reputation: 3930

You can use PyAudio to record audio and use np.frombuffer to convert it into a numpy array.

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()

If you want to record stereo instead of mono, you have to set channels to 2. Then you get an array with interleaved channels. You can reshape it like this:

frame = np.frombuffer(data, dtype=numpy.int16)       # interleaved channels
frame = np.stack((frame[::2], frame[1::2]), axis=0)  # channels on separate axes

Upvotes: 34

Related Questions