Oscilloscope XY Mode Animation From WAV File

Generating XY phase scope animation from a wav file.

Demo generated from the 3rd track of the album Cyclo. - Id, with a slightly different value for plt.xlim and plt.ylim.

You need to manually adjust dtype=np.int16 to e.g. something similar to dtype=np.int24 for 24bit wav.

import wave
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def gen_ani(fps,bitrate,name,file):
        fps=fps
        bitrate=bitrate

        wav_file = wave.open(file,'rb')
        n_samples = wav_file.getnframes()
        sample_freq = wav_file.getframerate()
        signal_wave = wav_file.readframes(n_samples)
        signal_array = np.frombuffer(signal_wave, dtype=np.int16)

        l_channel = signal_array[0::2]
        r_channel = signal_array[1::2]
        position = np.column_stack((l_channel,r_channel))

        frames = int(len(l_channel)/sample_freq*fps)
        point_num = int(len(l_channel)/frames)

        fig = plt.figure(figsize=(12, 12), dpi=80)
        plt.xlim(-33000,33000)
        plt.ylim(-33000,33000)
        scat = plt.scatter(position[0:point_num][:,0],position[0:point_num][:,1],s=1)

        def animate(i):
            a = i*point_num
            b = a+point_num*2
            scat.set_offsets(position[a:b])

        ani = animation.FuncAnimation(fig, animate, interval=1, frames=frames-10)
        WriterClass = animation.writers['ffmpeg']
        writer = WriterClass(fps=fps, bitrate=bitrate)
        ani.save(name,writer=writer)

e.g. gen_ani(60,1200,'generated.mp4','/tmp/example.wav').