Search code examples
pythonpyaudio

Decode PyAudio Record


I recorded some audio with PyAudio which I want to visualize. Currently I am saving the audio frames to a file and then again loading it with tensorflow:

def loadAudioFromFile(file):
    return decodeAudio(tf.io.read_file(file))


def decodeAudio(binary):
    foo, _ = tf.audio.decode_wav(binary, desired_channels=1)
    return tf.squeeze(foo, axis=-1)

The recording and saving:

RATE = 44100
RECORD_SECONDS = 1
CHUNK = 1024
CHANNELS = 1
p = pyaudio.PyAudio()

stream = p.open(format=pyaudio.paInt16,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                output=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")
# stop stream (4)
stream.stop_stream()
stream.close()

# close PyAudio (5)
p.terminate()
# save to file
file = wave.open("test.wav", 'wb')

file.setnchannels(1)
file.setsampwidth(p.get_sample_size(pyaudio.paInt16))
file.setframerate(RATE)

# Write and Close the File
file.writeframes(b''.join(frames))
file.close()

And the loading and plotting:

fig, axes = plt.subplots(1, 1, figsize=(10, 10))
ax = axes
audio = loadAudioFromFile("test.wav")
ax.plot(audio)
ax.set_yticks(np.arange(-1.2, 1.2, 0.2))
ax.set_title("audio")

But originally I wanted to load the recorded data directly, without first having to save it to the hard drive.

But when I do:

ax.plot(b''.join(frames))

it doesn't work, because of decoding issues (I think because of 16bit vs 8bit).

In C++ or similar, this is usually no problem for me, but I'm new to Python and a little bit lost :'D


Solution

  • frames is a list of byte strings. Each element is just a block of 2048 bytes. You need it to be a list of 16-bit elements. You can do that with 'array`.

    import array
    
    pcm = array.array('h')
    pcm.frombytes( b''.join(frames))
    ax.plot(pcm)
    ``